• SpringBoot+ElasticSearch 实现模糊查询,批量CRUD,排序,分页,高亮!


    一、导入elasticsearch依赖

    在pom.xml里加入如下依赖

    1. <dependency>
    2.       <groupId>org.springframework.boot</groupId>
    3.       <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    4. </dependency>

    非常重要:检查依赖版本是否与你当前所用的版本是否一致,如果不一致,会连接失败!

    二、创建高级客户端

    1. import org.apache.http.HttpHost;
    2. import org.elasticsearch.client.RestClient;
    3. import org.elasticsearch.client.RestHighLevelClient;
    4. import org.springframework.context.annotation.Bean;
    5. import org.springframework.context.annotation.Configuration;
    6. @Configuration
    7. public class ElasticSearchClientConfig {
    8.     @Bean
    9.     public RestHighLevelClient restHighLevelClient(){
    10.         RestHighLevelClient client = new RestHighLevelClient(
    11.                 RestClient.builder(
    12.                         new HttpHost("服务器IP"9200"http")));
    13.         return client;
    14.     }
    15. }

    三、基本用法

    1.创建、判断存在、删除索引

    1. import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
    2. import org.elasticsearch.action.support.master.AcknowledgedResponse;
    3. import org.elasticsearch.client.RequestOptions;
    4. import org.elasticsearch.client.RestHighLevelClient;
    5. import org.elasticsearch.client.indices.CreateIndexRequest;
    6. import org.elasticsearch.client.indices.CreateIndexResponse;
    7. import org.elasticsearch.client.indices.GetIndexRequest;
    8. import org.junit.jupiter.api.Test;
    9. import org.springframework.beans.factory.annotation.Autowired;
    10. import org.springframework.boot.test.context.SpringBootTest;
    11. import java.io.IOException;
    12. @SpringBootTest
    13. class ElasticsearchApplicationTests {
    14.  @Autowired
    15.  private RestHighLevelClient restHighLevelClient;
    16.  @Test
    17.  void testCreateIndex() throws IOException {
    18.   //1.创建索引请求
    19.   CreateIndexRequest request = new CreateIndexRequest("ljx666");
    20.   //2.客户端执行请求IndicesClient,执行create方法创建索引,请求后获得响应
    21.   CreateIndexResponse response=
    22.     restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
    23.   System.out.println(response);
    24.  }
    25.  @Test
    26.  void testExistIndex() throws IOException {
    27.         //1.查询索引请求
    28.   GetIndexRequest request=new GetIndexRequest("ljx666");
    29.         //2.执行exists方法判断是否存在
    30.   boolean exists=restHighLevelClient.indices().exists(request,RequestOptions.DEFAULT);
    31.   System.out.println(exists);
    32.  }
    33.  @Test
    34.  void testDeleteIndex() throws IOException {
    35.         //1.删除索引请求
    36.   DeleteIndexRequest request=new DeleteIndexRequest("ljx666");
    37.         //执行delete方法删除指定索引
    38.   AcknowledgedResponse delete = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
    39.   System.out.println(delete.isAcknowledged());
    40.  }
    41. }

    2.对文档的CRUD

    创建文档:

    注意:如果添加时不指定文档ID,他就会随机生成一个ID,ID唯一。

    创建文档时若该ID已存在,发送创建文档请求后会更新文档中的数据。

    1. @Test
    2. void testAddUser() throws IOException {
    3.  //1.创建对象
    4.  User user=new User("Go",21,new String[]{"内卷","吃饭"});
    5.  //2.创建请求
    6.  IndexRequest request=new IndexRequest("ljx666");
    7.  //3.设置规则 PUT /ljx666/_doc/1
    8.  //设置文档id=6,设置超时=1s等,不设置会使用默认的
    9.  //同时支持链式编程如 request.id("6").timeout("1s");
    10.  request.id("6");
    11.  request.timeout("1s");
    12.  //4.将数据放入请求,要将对象转化为json格式
    13.     //XContentType.JSON,告诉它传的数据是JSON类型
    14.  request.source(JSONValue.toJSONString(user), XContentType.JSON);
    15.     
    16.  //5.客户端发送请求,获取响应结果
    17.  IndexResponse indexResponse=restHighLevelClient.index(request,RequestOptions.DEFAULT);
    18.  System.out.println(indexResponse.toString());
    19.  System.out.println(indexResponse.status());
    20. }

    获取文档中的数据:

    1. @Test
    2. void testGetUser() throws IOException {
    3.  //1.创建请求,指定索引、文档id
    4.  GetRequest request=new GetRequest("ljx666","1");
    5.  GetResponse getResponse=restHighLevelClient.get(request,RequestOptions.DEFAULT);
    6.   
    7.  System.out.println(getResponse);//获取响应结果
    8.  //getResponse.getSource() 返回的是Map集合
    9.  System.out.println(getResponse.getSourceAsString());//获取响应结果source中内容,转化为字符串
    10.   
    11. }

    更新文档数据:

    注意:需要将User对象中的属性全部指定值,不然会被设置为空,如User只设置了名称,那么只有名称会被修改成功,其他会被修改为null。

    1. @Test
    2. void testUpdateUser() throws IOException {
    3.  //1.创建请求,指定索引、文档id
    4.  UpdateRequest request=new UpdateRequest("ljx666","6");
    5.  User user =new User("GoGo",21,new String[]{"内卷","吃饭"});
    6.  //将创建的对象放入文档中
    7.  request.doc(JSONValue.toJSONString(user),XContentType.JSON);
    8.  UpdateResponse updateResponse=restHighLevelClient.update(request,RequestOptions.DEFAULT);
    9.  System.out.println(updateResponse.status());//更新成功返回OK
    10. }

    删除文档:

    1. @Test
    2. void testDeleteUser() throws IOException {
    3.  //创建删除请求,指定要删除的索引与文档ID
    4.  DeleteRequest request=new DeleteRequest("ljx666","6");
    5.  DeleteResponse updateResponse=restHighLevelClient.delete(request,RequestOptions.DEFAULT);
    6.  System.out.println(updateResponse.status());//删除成功返回OK,没有找到返回NOT_FOUND
    7. }

    3.批量CRUD数据

    这里只列出了批量插入数据,其他与此类似。

    注意:hasFailures()方法是返回是否失败,即它的值为false时说明上传成功

    1. @Test
    2. void testBulkAddUser() throws IOException {
    3.  BulkRequest bulkRequest=new BulkRequest();
    4.  //设置超时
    5.  bulkRequest.timeout("10s");
    6.  ArrayList<User> list=new ArrayList<>();
    7.  list.add(new User("Java",25,new String[]{"内卷"}));
    8.  list.add(new User("Go",18,new String[]{"内卷"}));
    9.  list.add(new User("C",30,new String[]{"内卷"}));
    10.  list.add(new User("C++",26,new String[]{"内卷"}));
    11.  list.add(new User("Python",20,new String[]{"内卷"}));
    12.  int id=1;
    13.  //批量处理请求
    14.  for (User u :list){
    15.   //不设置id会生成随机id
    16.   bulkRequest.add(new IndexRequest("ljx666")
    17.     .id(""+(id++))
    18.     .source(JSONValue.toJSONString(u),XContentType.JSON));
    19.  }
    20.  BulkResponse bulkResponse=restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
    21.  System.out.println(bulkResponse.hasFailures());//是否执行失败,false为执行成功
    22. }

    4.查询所有、模糊查询、分页查询、排序、高亮显示

    1. @Test
    2. void testSearch() throws IOException {
    3.  SearchRequest searchRequest=new SearchRequest("ljx666");//里面可以放多个索引
    4.  SearchSourceBuilder sourceBuilder=new SearchSourceBuilder();//构造搜索条件
    5.  //此处可以使用QueryBuilders工具类中的方法
    6.  //1.查询所有
    7.  sourceBuilder.query(QueryBuilders.matchAllQuery());
    8.  //2.查询name中含有Java的
    9.  sourceBuilder.query(QueryBuilders.multiMatchQuery("java","name"));
    10.  //3.分页查询
    11.  sourceBuilder.from(0).size(5);
    12.     
    13.  //4.按照score正序排列
    14.  //sourceBuilder.sort(SortBuilders.scoreSort().order(SortOrder.ASC));
    15.  //5.按照id倒序排列(score会失效返回NaN)
    16.  //sourceBuilder.sort(SortBuilders.fieldSort("_id").order(SortOrder.DESC));
    17.  //6.给指定字段加上指定高亮样式
    18.  HighlightBuilder highlightBuilder=new HighlightBuilder();
    19.  highlightBuilder.field("name").preTags("").postTags("");
    20.  sourceBuilder.highlighter(highlightBuilder);
    21.   
    22.  searchRequest.source(sourceBuilder);
    23.  SearchResponse searchResponse=restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
    24.  //获取总条数
    25.  System.out.println(searchResponse.getHits().getTotalHits().value);
    26.  //输出结果数据(如果不设置返回条数,大于10条默认只返回10条)
    27.  SearchHit[] hits=searchResponse.getHits().getHits();
    28.  for(SearchHit hit :hits){
    29.   System.out.println("分数:"+hit.getScore());
    30.   Map<String,Object> source=hit.getSourceAsMap();
    31.   System.out.println("index->"+hit.getIndex());
    32.   System.out.println("id->"+hit.getId());
    33.   for(Map.Entry<String,Object> s:source.entrySet()){
    34.    System.out.println(s.getKey()+"--"+s.getValue());
    35.   }
    36.  }
    37. }

    四、总结

    1.大致流程

    创建对应的请求 --> 设置请求(添加规则,添加数据等) --> 执行对应的方法(传入请求,默认请求选项)–> 接收响应结果(执行方法返回值)–> 输出响应结果中需要的数据(source,status等)

    2.注意事项

    • 如果不指定id,会自动生成一个随机id

    • 正常情况下,不应该这样使用new IndexRequest(“ljx777”),如果索引发生改变了,那么代码都需要修改,可以定义一个枚举类或者一个专门存放常量的类,将变量用final static等进行修饰,并指定索引值。其他地方引用该常量即可,需要修改也只需修改该类即可。

    • elasticsearch相关的东西,版本都必须一致,不然会报错

    • elasticsearch很消耗内存,建议在内存较大的服务器上运行elasticsearch,否则会因为内存不足导致elasticsearch自动killed

  • 相关阅读:
    Dubbo入门
    从0到1了解大数据可视化平台
    Springboot vue旅游资讯网站管理系统
    CMake中option和cmake_dependent_option的使用
    【JavaWeb】 一文搞懂Request
    MySQL数据库中乐观锁和悲观锁【杭州多测师】【杭州多测师_王sir】
    Solon2 开发之IoC,八、动态代理的本质
    Servlet学生管理系统(萌新练手版)
    北大C++课后记录:文件读写的I/O流
    新版kafka可视化界面组件
  • 原文地址:https://blog.csdn.net/m0_71777195/article/details/128145358