方式二:SpringBoot 2.7.1 集成 ElasticSearch 7.4.0 的方式二 RestHighLevelClient_全栈编程网的博客-CSDN博客SpringBoot 2.7.1 集成 ElasticSearch 7.4.0 的方式二 RestHighLevelClienthttps://blog.csdn.net/ruanhao1203/article/details/125805034
目录
1. 安装ElasticSearch等相关软件
2. 概述
3. 项目代码
3.1 引入依赖
3.2 application.yml配置
3.3 创建索引hello对应的实体类
3.4 创建CRUD的dao
3.5 创建测试用的Controller类
4. 启动SpringBoot,测试CRUD
4.1 创建ES索引hello和mapping
4.2 新增数据到索引
4.3 查询数据
4.4 修改数据
4.5 删除数据
4.6 模糊查询content字段,并高亮显示
5. 分词器、高亮显示
5.1 ik分词器指定
5.2 高亮显示
Windows Docker 安装 ElasticSearch_全栈编程网的博客-CSDN博客
这种方式是spring-data提取了共性的CRUD功能,根据不同的操作资源实现不同的操作,如果操作的是MySQL那么就有 spring-data-mysql 实现对MySQL的CRUD功能。
Spring-data-elasticsearch方式,通过创建一个Repository接口 继承 ElasticsearchRepository 接口方式获取操作ElasticSearch的CRUD功能。
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-data-elasticsearch
org.projectlombok
lombok
1.16.10
com.alibaba
fastjson
1.2.70
spring:
application:
name: demo
elasticsearch:
uris: http://localhost:9200
server:
port: 8081
ElasticSearch 中有个索引 hello,这个实体类定义了索引的映射关系,每个属性都是索引对应mapping字段的设置,例如可以设置字段的类型,是否分词等信息,后面调用接口创建索引会根据这个类创建对应ES里面的索引hello
@Data
@NoArgsConstructor
@Accessors(chain = true)
@Document(indexName = "hello")
public class HelloEntity {
@Id
private Long id;
@Field(type = FieldType.Keyword)
private String firstCode;
@Field(type = FieldType.Keyword)
private String secordCode;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String content;
@Field(type = FieldType.Integer)
private Integer type;
public HelloEntity(Long id, String firstCode, String secordCode, String content, Integer type){
this.id=id;
this.firstCode=firstCode;
this.secordCode=secordCode;
this.content=content;
this.type=type;
}
}
spring-data-elasticsearch 中 ElasticSearchRepository 实现了对ElasticSearch 的CRUD操作,只要定义个HelloDao接口集成这个接口,就继承了CRUD功能。
对于自定义的对ES的操作方法,类似于jpa语法定义方法,就可以实现对ES的操作,如代码中例子所示,具体语法可以去学习一下
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.annotations.Highlight;
import org.springframework.data.elasticsearch.annotations.HighlightField;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import com.example.es.entity.HelloEntity;
public interface HelloDao extends ElasticsearchRepository {
/**
* 自定义ID范围查询
* @param begin
* @param end
* @param pageable
* @return
*/
Page findByIdBetween(int begin, int end, PageRequest pageable);
/**
* 自定义查询 ,高亮显示 firstCode
* @param firstCode
* @param secordCode
* @return
*/
@Highlight(fields = {
@HighlightField(name = "firstCode"),
@HighlightField(name = "secordCode")
})
List> findByFirstCodeOrSecordCode(String firstCode, String secordCode);
/**
* 模糊查询content
* @param content
* @return
*/
@Highlight(fields = {
@HighlightField(name = "content")
})
List> findByContent(String content);
}
集成了新建索引、删除索引、CRUD数据、分页查询、模糊查询、高亮显示等接口,基本涵盖了平时对ES的操作功能。
@RestController
@RequestMapping("es")
public class ElasticSearchController {
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@Autowired
private HelloDao helloDao;
/**
* 创建索引 hello
* @return
*/
@GetMapping("/createIndex")
public String create() {
boolean b = elasticsearchRestTemplate.indexOps(HelloEntity.class).create();
if (b) {
return "success";
}
return "fail";
}
/**
* 创建索引 hello,并创建mapping
* @return
*/
@GetMapping("/createIndexWithMapping")
public String createMapping() {
boolean b = elasticsearchRestTemplate.indexOps(HelloEntity.class).createWithMapping();
if (b) {
return "success";
}
return "fail";
}
/**
* 删除索引 hello
* @return
*/
@GetMapping("/deleteIndex")
public String deleteIndex() {
boolean b = elasticsearchRestTemplate.indexOps(HelloEntity.class).delete();
if (b) {
return "success";
}
return "fail";
}
/**
* 往hello索引中插入数据
* @param entity
* @return
*/
@PostMapping
public String add(@RequestBody HelloEntity entity) {
HelloEntity save = helloDao.save(entity);
System.out.println(save);
return "success";
}
/**
* 修改hello索引中的数据,根据ID修改
* @param entity
* @return
*/
@PutMapping
public String update(@RequestBody HelloEntity entity) {
HelloEntity save = helloDao.save(entity);
return "success";
}
/**
* 根据ID查询数据
* @param id
* @return
*/
@GetMapping("/{id}")
public String get(@PathVariable(value = "id") Long id) {
Optional byId = helloDao.findById(id);
boolean present = byId.isPresent();
if (present) {
return JSON.toJSONString(byId.get());
}
return null;
}
/**
* 分页查询
* @param pageDTO
* @return
*/
@GetMapping
public String getAll(@RequestBody PageDTO pageDTO) {
PageRequest pageable = PageRequest.of(pageDTO.getPage(), pageDTO.getSize());
Page all = helloDao.findAll(pageable);
return JSON.toJSONString(all);
}
/**
* 删除
* @param id
* @return
*/
@DeleteMapping("/{id}")
public String delete(@PathVariable(value = "id") Long id) {
helloDao.deleteById(id);
return "success";
}
/**
* 根据ID范围查询
* @return
*/
@GetMapping("/idBetween")
public String idBetween(@RequestParam(value = "begin") int begin,
@RequestParam(value = "end") int end,
@RequestParam(value = "page") int page,
@RequestParam(value = "size") int size
) {
PageRequest pageable = PageRequest.of(page, size);
Page all = helloDao.findByIdBetween(begin, end, pageable);
return JSON.toJSONString(all);
}
/**
* 根据 firstCode
* secordCode 查询
* @return
*/
@GetMapping("/findByFirstCodeOrSecordCode")
public String query(@RequestParam(value = "firstCode", required = false) String firstCode,
@RequestParam(value = "secordCode", required = false) String secordCode
) {
List> all = helloDao.findByFirstCodeOrSecordCode(firstCode, secordCode);
return JSON.toJSONString(all);
}
/**
* 模糊查询ik分词器分词的content字段
* @return
*/
@GetMapping("/findByContent")
public String queryContent(@RequestParam(value = "content", required = false) String content
) {
List> all = helloDao.findByContent(content);
return JSON.toJSONString(all);
}
}
DTO参数类
@Data
public class PageDTO {
private Integer page = 0;
private Integer size = 10;
}
调用相关接口测试功能。
调用接口: localhost:8080/es/createIndexWithMapping
创建成功后,验证索引:localhost:9200/hello ,返回值如下
字段解释
字段 | type | analyzer |
content | text | ik_max_word |
firstCode | keyword |
content字段的type是text,分词器是ik,表示这个字段会被分词,例如这个字段值是“中华人民共和国”,你搜索content字段可以模糊输入 共和国 、中华 都可以被搜到。
firstCode字段的type是 keyword,表示这是一个单词,不会被分词,例如这个字段值是“中华人民共和国”,那你输入共和国搜这个字段是搜不到的,属于精确查询才可以搜到
{
"hello":{
"aliases":{
},
"mappings":{
"properties":{
"_class":{
"type":"keyword",
"index":false,
"doc_values":false
},
"content":{
"type":"text",
"analyzer":"ik_max_word"
},
"firstCode":{
"type":"keyword"
},
"id":{
"type":"long"
},
"secordCode":{
"type":"keyword"
},
"type":{
"type":"integer"
}
}
},
"settings":{
"index":{
"refresh_interval":"1s",
"number_of_shards":"1",
"provided_name":"hello",
"creation_date":"1657701767667",
"store":{
"type":"fs"
},
"number_of_replicas":"1",
"uuid":"F6QnuExkSrKHcF_8NXcBtQ",
"version":{
"created":"7040099"
}
}
}
}
}
POST方式调用:http://localhost:8081/es
参数为:
{
"id": 1,
"firstCode": "小明",
"secordCode": "xiaoming",
"content": "中华人民共和国",
"type": 1
}
GET方式调用:http://localhost:8081/es/1
返回值:
{
"content": "中华人民共和国",
"firstCode": "小明",
"id": 1,
"secordCode": "xiaoming",
"type": 1
}
PUT方式调用:http://localhost:8081/es
{
"id": 1,
"firstCode": "小明小明小明",
"secordCode": "xm",
"content": "中华人民共和国",
"type": 2
}
再次查询ID 为1的数据
{
"content": "中华人民共和国",
"firstCode": "小明小明小明",
"id": 1,
"secordCode": "xm",
"type": 2
}
DELETE方式调用:http://localhost:8081/es/1
GET方式调用:http://localhost:8081/es/findByContent?content=中华
返回结果:标签包围的就是高亮显示
[
{
"content": {
"content": "中华人民共和国",
"id": 2
},
"highlightFields": {
"content": [
"中华人民共和国"
]
},
"id": "2",
"index": "hello",
"innerHits": {},
"matchedQueries": [],
"score": 0.13353139,
"sortValues": []
},
{
"content": {
"content": "中华人民共和国",
"firstCode": "小明小明小明",
"id": 1,
"secordCode": "xm",
"type": 2
},
"highlightFields": {
"content": [
"中华人民共和国"
]
},
"id": "1",
"index": "hello",
"innerHits": {},
"matchedQueries": [],
"score": 0.13353139,
"sortValues": []
}
]
通过Field注解里面 analyzer指定ik分词器
ik分词类型 | 特点 |
ik_max_word | 一般用这个,例如中华人民共和国,拆分的词可能重复,拆分的更细致。 |
ik_smart | 拆分的词不会重复,拆分不是很细致 |
通过注解指定高亮显示的content
@Highlight(fields = {
@HighlightField(name = "content")
})
public interface HelloDao extends ElasticsearchRepository {
/**
* 模糊查询content,高亮显示content
* @param content
* @return
*/
@Highlight(fields = {
@HighlightField(name = "content")
})
List> findByContent(String content);
}