Elasticsearch:RestClient+SearchSourceBuilder使用案例


1 前言

RestClient是較低層的API,這里使用基於其封裝的高層API,即RestHighLevelClient。

需要添加的依賴如下:

  1.  
    <dependency>
  2.  
    <groupId>org.elasticsearch</groupId>
  3.  
    <artifactId>elasticsearch</artifactId>
  4.  
    <version>5.6.10</version>
  5.  
    </dependency>
  6.  
    <dependency>
  7.  
    <groupId>org.elasticsearch.client</groupId>
  8.  
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
  9.  
    <version>5.6.10</version>
  10.  
    </dependency>

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

2 測試案例

測試代碼如下:

  1.  
    package com.xpleaf.es.leaf;
  2.  
     
  3.  
    import org.apache.http.HttpHost;
  4.  
    import org.elasticsearch.action.search.SearchRequest;
  5.  
    import org.elasticsearch.action.search.SearchResponse;
  6.  
    import org.elasticsearch.client.RestClient;
  7.  
    import org.elasticsearch.client.RestHighLevelClient;
  8.  
    import org.elasticsearch.common.unit.TimeValue;
  9.  
    import org.elasticsearch.index.query.*;
  10.  
    import org.elasticsearch.search.builder.SearchSourceBuilder;
  11.  
    import org.elasticsearch.search.sort.SortOrder;
  12.  
    import org.junit.After;
  13.  
    import org.junit.Before;
  14.  
    import org.junit.Test;
  15.  
     
  16.  
    /**
  17.  
    * @author xpleaf
  18.  
    * @GitHub https://github.com/xpleaf
  19.  
    * @Blog https://blog.51cto.com/xpleaf
  20.  
    * @date 2018/10/7 下午12:05
  21.  
    */
  22.  
    public class RestHighLevelClientTest {
  23.  
     
  24.  
    private HttpHost[] esHosts = new HttpHost[]{
  25.  
    new HttpHost("localhost", 9200)
  26.  
    };
  27.  
    private RestClient restClient = null;
  28.  
    private RestHighLevelClient client = null;
  29.  
    private BoolQueryBuilder boolQueryBuilder = null;
  30.  
     
  31.  
    @Before
  32.  
    public void init() throws Exception {
  33.  
    // 1.創建RestClient對象
  34.  
    restClient = RestClient.builder(esHosts).build();
  35.  
    client = new RestHighLevelClient(restClient);
  36.  
    // 2.創建BoolQueryBuilder對象
  37.  
    boolQueryBuilder = new BoolQueryBuilder();
  38.  
    // 3.設置boolQueryBuilder條件
  39.  
    MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders
  40.  
    .matchPhraseQuery( "key_word", "廣東");
  41.  
    MatchPhraseQueryBuilder matchPhraseQueryBuilder2 = QueryBuilders
  42.  
    .matchPhraseQuery( "key_word", "湖人");
  43.  
    RangeQueryBuilder rangeQueryBuilder = QueryBuilders
  44.  
    .rangeQuery( "postdate")
  45.  
    .from( "2016-01-01 00:00:00");
  46.  
    // 子boolQueryBuilder條件條件,用來表示查詢條件or的關系
  47.  
    BoolQueryBuilder childBoolQueryBuilder = new BoolQueryBuilder()
  48.  
    .should(matchPhraseQueryBuilder)
  49.  
    .should(matchPhraseQueryBuilder2);
  50.  
    // 4.添加查詢條件到boolQueryBuilder中
  51.  
    boolQueryBuilder
  52.  
    .must(childBoolQueryBuilder)
  53.  
    .must(rangeQueryBuilder);
  54.  
    }
  55.  
     
  56.  
    // 測試SearchSourceBuilder的搜索
  57.  
    @Test
  58.  
    public void test01() throws Exception {
  59.  
     
  60.  
    // 1.創建並設置SearchSourceBuilder對象
  61.  
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  62.  
    // 查詢條件--->生成DSL查詢語句
  63.  
    searchSourceBuilder.query(boolQueryBuilder);
  64.  
    // 第幾頁
  65.  
    searchSourceBuilder.from( 0);
  66.  
    // 每頁多少條數據
  67.  
    searchSourceBuilder.size( 100);
  68.  
    // 獲取的字段(列)和不需要獲取的列
  69.  
    searchSourceBuilder.fetchSource( new String[]{"postdate", "key_word"}, new String[]{});
  70.  
    // 設置排序規則
  71.  
    searchSourceBuilder.sort( "postdate", SortOrder.ASC);
  72.  
    // 設置超時時間為2s
  73.  
    searchSourceBuilder.timeout( new TimeValue(2000));
  74.  
     
  75.  
    // 2.創建並設置SearchRequest對象
  76.  
    SearchRequest searchRequest = new SearchRequest();
  77.  
    // 設置request要搜索的索引和類型
  78.  
    searchRequest.indices( "spnews").types("news");
  79.  
    // 設置SearchSourceBuilder查詢屬性
  80.  
    searchRequest.source(searchSourceBuilder);
  81.  
     
  82.  
    // 3.查詢
  83.  
    SearchResponse searchResponse = client.search(searchRequest);
  84.  
    System.out.println(searchResponse.toString());
  85.  
    }
  86.  
     
  87.  
    @After
  88.  
    public void after() throws Exception {
  89.  
    restClient.close();
  90.  
    }
  91.  
     
  92.  
    }

3 分析

3.1 Rest Json

上面測試案例的查詢條件:

  1.  
    // 2.創建BoolQueryBuilder對象
  2.  
    boolQueryBuilder = new BoolQueryBuilder();
  3.  
    // 3.設置boolQueryBuilder條件
  4.  
    MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders
  5.  
    .matchPhraseQuery( "key_word", "廣東");
  6.  
    MatchPhraseQueryBuilder matchPhraseQueryBuilder2 = QueryBuilders
  7.  
    .matchPhraseQuery( "key_word", "湖人");
  8.  
    RangeQueryBuilder rangeQueryBuilder = QueryBuilders
  9.  
    .rangeQuery( "postdate")
  10.  
    .from( "2016-01-01 00:00:00");
  11.  
    // 子boolQueryBuilder條件條件,用來表示查詢條件or的關系
  12.  
    BoolQueryBuilder childBoolQueryBuilder = new BoolQueryBuilder()
  13.  
    .should(matchPhraseQueryBuilder)
  14.  
    .should(matchPhraseQueryBuilder2);
  15.  
    // 4.添加查詢條件到boolQueryBuilder中
  16.  
    boolQueryBuilder
  17.  
    .must(childBoolQueryBuilder)
  18.  
    .must(rangeQueryBuilder);

實際上會轉化為如下的es查詢語句(可以debug一下,使用searchSourceBuilder就是用來做這種轉換):

  1.  
    {
  2.  
    "from" : 0,
  3.  
    "size" : 100,
  4.  
    "timeout" : "2000ms",
  5.  
    "query" : {
  6.  
    "bool" : {
  7.  
    "must" : [
  8.  
    {
  9.  
    "bool" : {
  10.  
    "should" : [
  11.  
    {
  12.  
    "match_phrase" : {
  13.  
    "key_word" : {
  14.  
    "query" : "廣東",
  15.  
    "slop" : 0,
  16.  
    "boost" : 1.0
  17.  
    }
  18.  
    }
  19.  
    },
  20.  
    {
  21.  
    "match_phrase" : {
  22.  
    "key_word" : {
  23.  
    "query" : "湖人",
  24.  
    "slop" : 0,
  25.  
    "boost" : 1.0
  26.  
    }
  27.  
    }
  28.  
    }
  29.  
    ],
  30.  
    "disable_coord" : false,
  31.  
    "adjust_pure_negative" : true,
  32.  
    "boost" : 1.0
  33.  
    }
  34.  
    },
  35.  
    {
  36.  
    "range" : {
  37.  
    "postdate" : {
  38.  
    "from" : "2016-01-01 00:00:00",
  39.  
    "to" : null,
  40.  
    "include_lower" : true,
  41.  
    "include_upper" : true,
  42.  
    "boost" : 1.0
  43.  
    }
  44.  
    }
  45.  
    }
  46.  
    ],
  47.  
    "disable_coord" : false,
  48.  
    "adjust_pure_negative" : true,
  49.  
    "boost" : 1.0
  50.  
    }
  51.  
    },
  52.  
    "_source" : {
  53.  
    "includes" : [
  54.  
    "postdate",
  55.  
    "key_word"
  56.  
    ],
  57.  
    "excludes" : [ ]
  58.  
    },
  59.  
    "sort" : [
  60.  
    {
  61.  
    "postdate" : {
  62.  
    "order" : "asc"
  63.  
    }
  64.  
    }
  65.  
    ]
  66.  
    }

3.2 match query VS match_phrase query

注意其差別:

    • match query:會對查詢語句進行分詞,分詞后查詢語句中的任何一個詞項被匹配,文檔就會被搜索到。如果想查詢匹配所有關鍵詞的文檔,可以用and操作符連接;
    • match_phrase query:滿足下面兩個條件才會被搜索到
      • (1)分詞后所有詞項都要出現在該字段中
      • (2)字段中的詞項順序要一致

1 前言

RestClient是較低層的API,這里使用基於其封裝的高層API,即RestHighLevelClient。

需要添加的依賴如下:

  1.  
    <dependency>
  2.  
    <groupId>org.elasticsearch </groupId>
  3.  
    <artifactId>elasticsearch </artifactId>
  4.  
    <version>5.6.10 </version>
  5.  
    </dependency>
  6.  
    <dependency>
  7.  
    <groupId>org.elasticsearch.client </groupId>
  8.  
    <artifactId>elasticsearch-rest-high-level-client </artifactId>
  9.  
    <version>5.6.10 </version>
  10.  
    </dependency>

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

2 測試案例

測試代碼如下:

  1.  
    package com.xpleaf.es.leaf;
  2.  
     
  3.  
    import org.apache.http.HttpHost;
  4.  
    import org.elasticsearch.action.search.SearchRequest;
  5.  
    import org.elasticsearch.action.search.SearchResponse;
  6.  
    import org.elasticsearch.client.RestClient;
  7.  
    import org.elasticsearch.client.RestHighLevelClient;
  8.  
    import org.elasticsearch.common.unit.TimeValue;
  9.  
    import org.elasticsearch.index.query.*;
  10.  
    import org.elasticsearch.search.builder.SearchSourceBuilder;
  11.  
    import org.elasticsearch.search.sort.SortOrder;
  12.  
    import org.junit.After;
  13.  
    import org.junit.Before;
  14.  
    import org.junit.Test;
  15.  
     
  16.  
    /**
  17.  
    * @author xpleaf
  18.  
    * @GitHub https://github.com/xpleaf
  19.  
    * @Blog https://blog.51cto.com/xpleaf
  20.  
    * @date 2018/10/7 下午12:05
  21.  
    */
  22.  
    public class RestHighLevelClientTest {
  23.  
     
  24.  
    private HttpHost[] esHosts = new HttpHost[]{
  25.  
    new HttpHost( "localhost", 9200)
  26.  
    };
  27.  
    private RestClient restClient = null;
  28.  
    private RestHighLevelClient client = null;
  29.  
    private BoolQueryBuilder boolQueryBuilder = null;
  30.  
     
  31.  
    @Before
  32.  
    public void init() throws Exception {
  33.  
    // 1.創建RestClient對象
  34.  
    restClient = RestClient.builder(esHosts).build();
  35.  
    client = new RestHighLevelClient(restClient);
  36.  
    // 2.創建BoolQueryBuilder對象
  37.  
    boolQueryBuilder = new BoolQueryBuilder();
  38.  
    // 3.設置boolQueryBuilder條件
  39.  
    MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders
  40.  
    .matchPhraseQuery( "key_word", "廣東");
  41.  
    MatchPhraseQueryBuilder matchPhraseQueryBuilder2 = QueryBuilders
  42.  
    .matchPhraseQuery( "key_word", "湖人");
  43.  
    RangeQueryBuilder rangeQueryBuilder = QueryBuilders
  44.  
    .rangeQuery( "postdate")
  45.  
    .from( "2016-01-01 00:00:00");
  46.  
    // 子boolQueryBuilder條件條件,用來表示查詢條件or的關系
  47.  
    BoolQueryBuilder childBoolQueryBuilder = new BoolQueryBuilder()
  48.  
    .should(matchPhraseQueryBuilder)
  49.  
    .should(matchPhraseQueryBuilder2);
  50.  
    // 4.添加查詢條件到boolQueryBuilder中
  51.  
    boolQueryBuilder
  52.  
    .must(childBoolQueryBuilder)
  53.  
    .must(rangeQueryBuilder);
  54.  
    }
  55.  
     
  56.  
    // 測試SearchSourceBuilder的搜索
  57.  
    @Test
  58.  
    public void test01() throws Exception {
  59.  
     
  60.  
    // 1.創建並設置SearchSourceBuilder對象
  61.  
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  62.  
    // 查詢條件--->生成DSL查詢語句
  63.  
    searchSourceBuilder.query(boolQueryBuilder);
  64.  
    // 第幾頁
  65.  
    searchSourceBuilder.from( 0);
  66.  
    // 每頁多少條數據
  67.  
    searchSourceBuilder.size( 100);
  68.  
    // 獲取的字段(列)和不需要獲取的列
  69.  
    searchSourceBuilder.fetchSource( new String[]{ "postdate", "key_word"}, new String[]{});
  70.  
    // 設置排序規則
  71.  
    searchSourceBuilder.sort( "postdate", SortOrder.ASC);
  72.  
    // 設置超時時間為2s
  73.  
    searchSourceBuilder.timeout( new TimeValue( 2000));
  74.  
     
  75.  
    // 2.創建並設置SearchRequest對象
  76.  
    SearchRequest searchRequest = new SearchRequest();
  77.  
    // 設置request要搜索的索引和類型
  78.  
    searchRequest.indices( "spnews").types( "news");
  79.  
    // 設置SearchSourceBuilder查詢屬性
  80.  
    searchRequest.source(searchSourceBuilder);
  81.  
     
  82.  
    // 3.查詢
  83.  
    SearchResponse searchResponse = client.search(searchRequest);
  84.  
    System.out.println(searchResponse.toString());
  85.  
    }
  86.  
     
  87.  
    @After
  88.  
    public void after() throws Exception {
  89.  
    restClient.close();
  90.  
    }
  91.  
     
  92.  
    }

3 分析

3.1 Rest Json

上面測試案例的查詢條件:

  1.  
    // 2.創建BoolQueryBuilder對象
  2.  
    boolQueryBuilder = new BoolQueryBuilder();
  3.  
    // 3.設置boolQueryBuilder條件
  4.  
    MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders
  5.  
    .matchPhraseQuery( "key_word", "廣東");
  6.  
    MatchPhraseQueryBuilder matchPhraseQueryBuilder2 = QueryBuilders
  7.  
    .matchPhraseQuery( "key_word", "湖人");
  8.  
    RangeQueryBuilder rangeQueryBuilder = QueryBuilders
  9.  
    .rangeQuery( "postdate")
  10.  
    .from( "2016-01-01 00:00:00");
  11.  
    // 子boolQueryBuilder條件條件,用來表示查詢條件or的關系
  12.  
    BoolQueryBuilder childBoolQueryBuilder = new BoolQueryBuilder()
  13.  
    .should(matchPhraseQueryBuilder)
  14.  
    .should(matchPhraseQueryBuilder2);
  15.  
    // 4.添加查詢條件到boolQueryBuilder中
  16.  
    boolQueryBuilder
  17.  
    .must(childBoolQueryBuilder)
  18.  
    .must(rangeQueryBuilder);

實際上會轉化為如下的es查詢語句(可以debug一下,使用searchSourceBuilder就是用來做這種轉換):

  1.  
    {
  2.  
    "from" : 0,
  3.  
    "size" : 100,
  4.  
    "timeout" : "2000ms",
  5.  
    "query" : {
  6.  
    "bool" : {
  7.  
    "must" : [
  8.  
    {
  9.  
    "bool" : {
  10.  
    "should" : [
  11.  
    {
  12.  
    "match_phrase" : {
  13.  
    "key_word" : {
  14.  
    "query" : "廣東",
  15.  
    "slop" : 0,
  16.  
    "boost" : 1.0
  17.  
    }
  18.  
    }
  19.  
    },
  20.  
    {
  21.  
    "match_phrase" : {
  22.  
    "key_word" : {
  23.  
    "query" : "湖人",
  24.  
    "slop" : 0,
  25.  
    "boost" : 1.0
  26.  
    }
  27.  
    }
  28.  
    }
  29.  
    ],
  30.  
    "disable_coord" : false,
  31.  
    "adjust_pure_negative" : true,
  32.  
    "boost" : 1.0
  33.  
    }
  34.  
    },
  35.  
    {
  36.  
    "range" : {
  37.  
    "postdate" : {
  38.  
    "from" : "2016-01-01 00:00:00",
  39.  
    "to" : null,
  40.  
    "include_lower" : true,
  41.  
    "include_upper" : true,
  42.  
    "boost" : 1.0
  43.  
    }
  44.  
    }
  45.  
    }
  46.  
    ],
  47.  
    "disable_coord" : false,
  48.  
    "adjust_pure_negative" : true,
  49.  
    "boost" : 1.0
  50.  
    }
  51.  
    },
  52.  
    "_source" : {
  53.  
    "includes" : [
  54.  
    "postdate",
  55.  
    "key_word"
  56.  
    ],
  57.  
    "excludes" : [ ]
  58.  
    },
  59.  
    "sort" : [
  60.  
    {
  61.  
    "postdate" : {
  62.  
    "order" : "asc"
  63.  
    }
  64.  
    }
  65.  
    ]
  66.  
    }

3.2 match query VS match_phrase query

注意其差別:

  • match query:會對查詢語句進行分詞,分詞后查詢語句中的任何一個詞項被匹配,文檔就會被搜索到。如果想查詢匹配所有關鍵詞的文檔,可以用and操作符連接;
  • match_phrase query:滿足下面兩個條件才會被搜索到
    • (1)分詞后所有詞項都要出現在該字段中
    • (2)字段中的詞項順序要一致


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM