需求:对“昵称”进行“全文检索查询”,对“账号”进行“精确查询”。
认识 Elasticsearch
1. ES 的倒排索引
2. ES 与 mysql 的区别
3. ES 的数据结构与表结构
注:id不为long型,而是keyword。即,不参与分词。
4. ES 分词器的种类:
5. ES 增删改查:
6. ES 查询方式:
配置 Elasticsearch
- 下载 Elasticsearch
- Windows10环境下安装Es7_windows安装es7-CSDN博客
- 7.x 和 8.x 差距比较大(8.x 版本默认有ssl 认证、用户密码登录,且在 Spring 中的操作差别有点大)。采用版本是7.12.1。
- 有高、低版本。采用高版本。
- 已经不支持 java 访问 ES,而是 java request 请求的方式访问 ES。
- 在Spring boot 配置 ES
- 在 xml 中引入依赖。且需要在 properties 强制指定 ES 版本为 7.12.1。
- 在Spring boot 配置 FastJson
- 在 xml 中引入依赖。且需要指定版本为 1.2.68。1.1.x 不支持 LocalDateTime。
- 在Spring boot 配置 RabbitMQ
- 在 xml 中引入依赖。
- 在 yml 中配置 RabbitMQ。
实现 Elasticsearch
1. 增删改:数据同步
异步通知的操作:
2. 查询 + 分页
示例,对“昵称”进行全文检索查询:
1. 创建一个配置类,注入一个 bean 方法,把向 ES 发送请求的 client 注入 IOC。
@Configuration
public class EsConfig {
@Bean
public RestHighLevelClient clien(){
return new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://localhost:9200")
));
}
}
2. POJO 中封装三个类:
收到前端的类 EsPageParams
@Data
public class EsPageParams {
private String key;
private Integer page;
private Integer size;
}
发给前端的类 EsPageResult
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EsPageResult {
private Long total;
private List<User> users;
}
数据库的类 User
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
@TableId(type = IdType.AUTO)
private Long id; //ID
private String username; //用户名
private String password; //密码
private String niCheng; //姓名
private Integer gender;
private String location;
private String txImageName;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}
(如果 ES 和 mysql 数据库不一致,还需要一个 ES 类)
3. Controller 层:接受请求,发送给 Service 层。
4. Service 层:对 user 索引表的 niCheng 字段进行检索,检索方式是倒排索引。最终结果返回给 Controller 层。
@Service
public class EsService {
@Autowired
private RestHighLevelClient client;
@Autowired
private UserService userService;
public EsPageResult search(EsPageParams esPageParams) throws IOException {
// 1.准备request
SearchRequest request = new SearchRequest("user");
// 2. 准备DSL
String key = esPageParams.getKey();
request.source().query(QueryBuilders.matchQuery("niCheng",key));
int page = esPageParams.getPage();
int size = esPageParams.getSize();
request.source().from((page - 1) * size).size(size);
// 3. 发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 4.解析响应
return handleResponse(response);
}
private EsPageResult handleResponse(SearchResponse response){
SearchHits searchHits = response.getHits();
long total = searchHits.getTotalHits().value;
System.out.println("共搜索到"+total+"条数据");
SearchHit[] hits = searchHits.getHits();
List<User> users = new ArrayList<>();
for(SearchHit hit : hits){
String json = hit.getSourceAsString();
User user = JSON.parseObject(json, User.class);
users.add(user);
}
return new EsPageResult(total, users);
}