Spring Boot集成Elasticsearch采用RestHighLevelClient实现查询

630 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第19天,点击查看活动详情

前言

上一章讲解了Spring Boot集成Elasticsearch的EsProductRepository实现查询,官方建议使RestHighLevelClient实现相关查询,本文将讲解Spring Boot 采用RestHighLevelClient实现查询

前期准备

Spring Boot集成Elasticsearch经常会遇到版本问题,下面我列举下Spring Boot与ES对应的版本列表,这样大家在也不会担心版本问题了。

图片.png

通过这个图我们可以得知,Spring Boot2.3+版本以后,会自动引用elasticsearch-rest-high-level-client7.0+以上的的版本,所以ES客户端也需要安装7.0+以上的版本。

pom.xml引入相关jar包

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
</parent>

 <dependency>
     <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  </dependency>

说明:网上很多人还都在使用的是elasticsearch-rest-high-level-client6.0+的版本,而引入Spring2.3.3版本会自动引入elasticsearch-rest-high-level-client7.0+的版本,其依赖关系如下:

图片.png

基本使用

创建索引

请求示例

http://localhost:9090/hight/addProduct

{
     "id":"9",
	 "skuNo":"sku0009",
	 "title":"小桥流水人家",
	  "price":"10.00",
      "createDate":"1655132070891"
}

Controller实现如下

    @Autowired
    private RestHighLevelClient client;
    
    @PostMapping("/addProduct")
    public Result addProduct(@RequestBody Product product) throws IOException 
    {
        IndexRequest indexRequest =new IndexRequest("product");
        indexRequest.id(product.getId());
        String jsonString=JSON.toJSONString(product);
        indexRequest.source(jsonString,XContentType.JSON);
        IndexResponse response = client.index(indexRequest,RequestOptions.DEFAULT);
        return Result.success(response);
    }

说明:XContentType可以支持多种数据格式,

  • JSON:JSON数据格式
  • Simple:简单对象
  • YAML: YAML数据格式
  • CBOR:简明二进制对象展现

词条匹配

请求示例

http://localhost:9090/hight/search?indexName=product&key=title&value=水

Conroller实现

 @GetMapping("/search")
    public Result search(String indexName,String key,String value) throws IOException 
    {
        //设置多个文档
        SearchRequest request =new SearchRequest(indexName);
        SearchSourceBuilder sourceBuilder =new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.termQuery(key,value));
        request.source(sourceBuilder);
        SearchResponse response =client.search(request, RequestOptions.DEFAULT);
        return Result.success(response);
    }

查询结果

{
    "data": [
        {
            "score": 1.4831866,
            "id": "8",
            "type": "_doc",
            "nestedIdentity": null,
            "version": -1,
            "seqNo": -2,
            "primaryTerm": 0,
            "fields": {},
            "highlightFields": {},
            "sortValues": [],
            "matchedQueries": [],
            "explanation": null,
            "shard": null,
            "index": "product",
            "clusterAlias": null,
            "sourceAsMap": {
                "price": 109.0,
                "skuNo": "sku0008",
                "id": "8",
                "title": "水浒传",
                "createDate": 1655132070891
            },
            "innerHits": null,
            "rawSortValues": [],
            "sourceRef": {
                "fragment": true
            },
            "sourceAsString": "{\"createDate\":1655132070891,\"id\":\"8\",\"price\":109.0,\"skuNo\":\"sku0008\",\"title\":\"水浒传\"}",
            "fragment": false
        },
        {
            "score": 1.1272218,
            "id": "9",
            "type": "_doc",
            "nestedIdentity": null,
            "version": -1,
            "seqNo": -2,
            "primaryTerm": 0,
            "fields": {},
            "highlightFields": {},
            "sortValues": [],
            "matchedQueries": [],
            "explanation": null,
            "shard": null,
            "index": "product",
            "clusterAlias": null,
            "sourceAsMap": {
                "price": 10.0,
                "skuNo": "sku0009",
                "id": "9",
                "title": "小桥流水人家",
                "createDate": 1655132070891
            },
            "innerHits": null,
            "rawSortValues": [],
            "sourceRef": {
                "fragment": true
            },
            "sourceAsString": "{\"createDate\":1655132070891,\"id\":\"9\",\"price\":10.0,\"skuNo\":\"sku0009\",\"title\":\"小桥流水人家\"}",
            "fragment": false
        }
    ],
    "code": 200,
    "msg": "操作成功"
}

说明:查询包含水字的词条的所有数据。

模糊查询

http://localhost:9090/hight/wildSearch?indexName=product&key=title&value=水

Conroller实现

   @GetMapping("/wildSearch")
    public Result wildSearch(String indexName,String key,String value) throws IOException 
    {
        //设置多个文档
        SearchRequest request =new SearchRequest(indexName);
        SearchSourceBuilder sourceBuilder =new SearchSourceBuilder();
        //设置模糊查询的条件
        WildcardQueryBuilder  matchQueryBuilder =new WildcardQueryBuilder(key,"*"+value+"*");
        sourceBuilder.query(matchQueryBuilder);
        request.source(sourceBuilder);
        SearchResponse response =client.search(request, RequestOptions.DEFAULT);
        return Result.success(response);
    }

查询结果

{
    "data": [
        {
            "score": 1.0,
            "id": "2",
            "type": "_doc",
            "nestedIdentity": null,
            "version": -1,
            "seqNo": -2,
            "primaryTerm": 0,
            "fields": {},
            "highlightFields": {},
            "sortValues": [],
            "matchedQueries": [],
            "explanation": null,
            "shard": null,
            "index": "product",
            "clusterAlias": null,
            "sourceAsMap": {
                "price": 99.0,
                "skuNo": "sku0002",
                "id": "2",
                "title": "java从入门到精通",
                "createDate": 1655132070891
            },
            "innerHits": null,
            "rawSortValues": [],
            "sourceRef": {
                "fragment": true
            },
            "sourceAsString": "{\"createDate\":1655132070891,\"id\":\"2\",\"price\":99.0,\"skuNo\":\"sku0002\",\"title\":\"java从入门到精通\"}",
            "fragment": false
        },
        {
            "score": 1.0,
            "id": "3",
            "type": "_doc",
            "nestedIdentity": null,
            "version": -1,
            "seqNo": -2,
            "primaryTerm": 0,
            "fields": {},
            "highlightFields": {},
            "sortValues": [],
            "matchedQueries": [],
            "explanation": null,
            "shard": null,
            "index": "product",
            "clusterAlias": null,
            "sourceAsMap": {
                "price": 89.0,
                "skuNo": "sku0003",
                "id": "3",
                "title": "java编程思想",
                "createDate": 1655132070891
            },
            "innerHits": null,
            "rawSortValues": [],
            "sourceRef": {
                "fragment": true
            },
            "sourceAsString": "{\"createDate\":1655132070891,\"id\":\"3\",\"price\":89.0,\"skuNo\":\"sku0003\",\"title\":\"java编程思想\"}",
            "fragment": false
        },
        {
            "score": 1.0,
            "id": "4",
            "type": "_doc",
            "nestedIdentity": null,
            "version": -1,
            "seqNo": -2,
            "primaryTerm": 0,
            "fields": {},
            "highlightFields": {},
            "sortValues": [],
            "matchedQueries": [],
            "explanation": null,
            "shard": null,
            "index": "product",
            "clusterAlias": null,
            "sourceAsMap": {
                "price": 89.0,
                "skuNo": "sku0004",
                "id": "4",
                "title": "java设计模式",
                "createDate": 1655132070891
            },
            "innerHits": null,
            "rawSortValues": [],
            "sourceRef": {
                "fragment": true
            },
            "sourceAsString": "{\"createDate\":1655132070891,\"id\":\"4\",\"price\":89.0,\"skuNo\":\"sku0004\",\"title\":\"java设计模式\"}",
            "fragment": false
        }
    ],
    "code": 200,
    "msg": "操作成功"
}

从查询的结果来看,包含java分词的都模糊查询出来了。

范围查询

http://localhost:9090/hight/rangeSearch?indexName=product&beginTime=2022-06-01&endTime=2022-06-30

Conroller实现

 @GetMapping("/rangeSearch")
    public Result rangeSearch(String indexName,String beginTime,String endTime) throws IOException 
    {
        //设置多个文档
        SearchRequest request =new SearchRequest(indexName);
        SearchSourceBuilder sourceBuilder =new SearchSourceBuilder();
        //设置多个文档类型
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.rangeQuery("createDate")
                        .gte(beginTime)
                        .lte(endTime)
                        .format("yyyy-MM-dd")
                        .timeZone("+08:00"));
        sourceBuilder.query(boolQueryBuilder);
        request.source(sourceBuilder);
        SearchResponse response =client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        SearchHit[] searchHits = hits.getHits();
        return Result.success(searchHits);
    }

查询结果

{
    "data": {
        "content": [
            {
                "id": "2",
                "skuNo": "sku0002",
                "title": "java从入门到精通",
                "price": 99.0,
                "createDate": "2022-06-13T14:54:30.891+00:00"
            },
            {
                "id": "3",
                "skuNo": "sku0003",
                "title": "java编程思想",
                "price": 89.0,
                "createDate": "2022-06-13T14:54:30.891+00:00"
            },
            {
                "id": "4",
                "skuNo": "sku0004",
                "title": "java设计模式",
                "price": 89.0,
                "createDate": "2022-06-13T14:54:30.891+00:00"
            },
            {
                "id": "5",
                "skuNo": "sku0005",
                "title": "Spring编程",
                "price": 89.0,
                "createDate": "2022-06-13T14:54:30.891+00:00"
            },
            {
                "id": "6",
                "skuNo": "sku0006",
                "title": "Spring Boot编程",
                "price": 89.0,
                "createDate": "2022-06-13T14:54:30.891+00:00"
            },
            {
                "id": "8",
                "skuNo": "sku0008",
                "title": "水浒传",
                "price": 109.0,
                "createDate": "2022-06-13T14:54:30.891+00:00"
            },
            {
                "id": "9",
                "skuNo": "sku0009",
                "title": "小桥流水人家",
                "price": 10.0,
                "createDate": "2022-06-13T14:54:30.891+00:00"
            }
        ],
        "pageable": {
            "sort": {
                "sorted": false,
                "unsorted": true,
                "empty": true
            },
            "offset": 0,
            "pageNumber": 0,
            "pageSize": 7,
            "paged": true,
            "unpaged": false
        },
        "aggregations": null,
        "scrollId": null,
        "maxScore": 1.0,
        "totalElements": 7,
        "totalPages": 1,
        "number": 0,
        "size": 7,
        "sort": {
            "sorted": false,
            "unsorted": true,
            "empty": true
        },
        "numberOfElements": 7,
        "first": true,
        "last": true,
        "empty": false
    },
    "code": 200,
    "msg": "操作成功"
}

总结

本文讲解了Spring Boot集成RestHighLevelClient实现基础查询,如有疑问请随时提问。