热门IT资讯网

Elasticsearch:RestClient+SearchSourceBuilder使用案例

发表于:2024-11-25 作者:热门IT资讯网编辑
编辑最后更新 2024年11月25日,1 前言RestClient是较低层的API,这里使用基于其封装的高层API,即RestHighLevelClient。需要添加的依赖如下: org.elasticsearch elast

1 前言

RestClient是较低层的API,这里使用基于其封装的高层API,即RestHighLevelClient。

需要添加的依赖如下:

    org.elasticsearch    elasticsearch    5.6.10    org.elasticsearch.client    elasticsearch-rest-high-level-client    5.6.10

较低版本的es可能不支持RestHighLevelClient。
查看一下其maven中央仓库:https://mvnrepository.com/artifact/org.elasticsearch.client/elasticsearch-rest-high-level-client
可以看到,5.6以上的版本才有。

2 测试案例

测试代码如下:

package com.xpleaf.es.leaf;import org.apache.http.HttpHost;import org.elasticsearch.action.search.SearchRequest;import org.elasticsearch.action.search.SearchResponse;import org.elasticsearch.client.RestClient;import org.elasticsearch.client.RestHighLevelClient;import org.elasticsearch.common.unit.TimeValue;import org.elasticsearch.index.query.*;import org.elasticsearch.search.builder.SearchSourceBuilder;import org.elasticsearch.search.sort.SortOrder;import org.junit.After;import org.junit.Before;import org.junit.Test;/** * @author xpleaf * @GitHub https://github.com/xpleaf * @Blog https://blog.51cto.com/xpleaf * @date 2018/10/7 下午12:05 */public class RestHighLevelClientTest {    private HttpHost[] esHosts = new HttpHost[]{            new HttpHost("localhost", 9200)    };    private RestClient restClient = null;    private RestHighLevelClient client = null;    private BoolQueryBuilder boolQueryBuilder = null;    @Before    public void init() throws Exception {        // 1.创建RestClient对象        restClient = RestClient.builder(esHosts).build();        client = new RestHighLevelClient(restClient);        // 2.创建BoolQueryBuilder对象        boolQueryBuilder = new BoolQueryBuilder();        // 3.设置boolQueryBuilder条件        MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders                .matchPhraseQuery("key_word", "广东");        MatchPhraseQueryBuilder matchPhraseQueryBuilder2 = QueryBuilders                .matchPhraseQuery("key_word", "湖人");        RangeQueryBuilder rangeQueryBuilder = QueryBuilders                .rangeQuery("postdate")                .from("2016-01-01 00:00:00");        // 子boolQueryBuilder条件条件,用来表示查询条件or的关系        BoolQueryBuilder childBoolQueryBuilder = new BoolQueryBuilder()                .should(matchPhraseQueryBuilder)                .should(matchPhraseQueryBuilder2);        // 4.添加查询条件到boolQueryBuilder中        boolQueryBuilder                .must(childBoolQueryBuilder)                .must(rangeQueryBuilder);    }    // 测试SearchSourceBuilder的搜索    @Test    public void test01() throws Exception {        // 1.创建并设置SearchSourceBuilder对象        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();        // 查询条件--->生成DSL查询语句        searchSourceBuilder.query(boolQueryBuilder);        // 第几页        searchSourceBuilder.from(0);        // 每页多少条数据        searchSourceBuilder.size(100);        // 获取的字段(列)和不需要获取的列        searchSourceBuilder.fetchSource(new String[]{"postdate", "key_word"}, new String[]{});        // 设置排序规则        searchSourceBuilder.sort("postdate", SortOrder.ASC);        // 设置超时时间为2s        searchSourceBuilder.timeout(new TimeValue(2000));        // 2.创建并设置SearchRequest对象        SearchRequest searchRequest = new SearchRequest();        // 设置request要搜索的索引和类型        searchRequest.indices("spnews").types("news");        // 设置SearchSourceBuilder查询属性        searchRequest.source(searchSourceBuilder);        // 3.查询        SearchResponse searchResponse = client.search(searchRequest);        System.out.println(searchResponse.toString());    }    @After    public void after() throws Exception {        restClient.close();    }}

3 分析

3.1 Rest Json

上面测试案例的查询条件:

// 2.创建BoolQueryBuilder对象boolQueryBuilder = new BoolQueryBuilder();// 3.设置boolQueryBuilder条件MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders                .matchPhraseQuery("key_word", "广东");MatchPhraseQueryBuilder matchPhraseQueryBuilder2 = QueryBuilders                .matchPhraseQuery("key_word", "湖人");RangeQueryBuilder rangeQueryBuilder = QueryBuilders                .rangeQuery("postdate")    .from("2016-01-01 00:00:00");// 子boolQueryBuilder条件条件,用来表示查询条件or的关系BoolQueryBuilder childBoolQueryBuilder = new BoolQueryBuilder()    .should(matchPhraseQueryBuilder)    .should(matchPhraseQueryBuilder2);// 4.添加查询条件到boolQueryBuilder中boolQueryBuilder                .must(childBoolQueryBuilder)    .must(rangeQueryBuilder);

实际上会转化为如下的es查询语句(可以debug一下,使用searchSourceBuilder就是用来做这种转换):

{  "from" : 0,  "size" : 100,  "timeout" : "2000ms",  "query" : {    "bool" : {      "must" : [        {          "bool" : {            "should" : [              {                "match_phrase" : {                  "key_word" : {                    "query" : "广东",                    "slop" : 0,                    "boost" : 1.0                  }                }              },              {                "match_phrase" : {                  "key_word" : {                    "query" : "湖人",                    "slop" : 0,                    "boost" : 1.0                  }                }              }            ],            "disable_coord" : false,            "adjust_pure_negative" : true,            "boost" : 1.0          }        },        {          "range" : {            "postdate" : {              "from" : "2016-01-01 00:00:00",              "to" : null,              "include_lower" : true,              "include_upper" : true,              "boost" : 1.0            }          }        }      ],      "disable_coord" : false,      "adjust_pure_negative" : true,      "boost" : 1.0    }  },  "_source" : {    "includes" : [      "postdate",      "key_word"    ],    "excludes" : [ ]  },  "sort" : [    {      "postdate" : {        "order" : "asc"      }    }  ]}

3.2 match query VS match_phrase query

注意其差别:

  • match query:会对查询语句进行分词,分词后查询语句中的任何一个词项被匹配,文档就会被搜索到。如果想查询匹配所有关键词的文档,可以用and操作符连接;
  • match_phrase query:满足下面两个条件才会被搜索到
    • (1)分词后所有词项都要出现在该字段中
    • (2)字段中的词项顺序要一致
0