es 布爾查詢


布爾查詢是常用的復合查詢,它把多個子查詢組合成一個布爾表達式。布爾查詢可以按照各個子查詢的具體匹配程度對文檔進行打分計算。

 

 1.must查詢

當查詢中包含must查詢時,相當於邏輯查詢中的“與”查詢。命中的文檔必須匹配該子查詢的結果,並且ES會將該子查詢與文檔的匹配程度值加入總得分里。must搜索包含一個數組,可以把其他的term級別的查詢及布爾查詢放入其中。

示例:

GET /hotel/_search 
{ 
  "query": { 
    "bool": { 
      "must": [                //must查詢,數組內可封裝各類子查詢 
        {                      //第一個子查詢:城市為北京 
          "term": { 
            "city": { 
              "value": "北京" 
            } 
          } 
        }, 
        {                    //第二個子查詢:價格>=350且價格<=400  
          "range": { 
            "price": { 
              "gte": 350, 
              "lte": 400 
            } 
          } 
        } 
      ] 
    } 
  } 
} 

在Java客戶端上構建must搜索時,可以使用QueryBuilders.boolQuery().must()進行構建,上面的range查詢例子改寫成Java客戶端請求的形式為:

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//構建城市term查詢
TermQueryBuilder termQueryIsReady = QueryBuilders.termQuery("city", "北京");
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price").gte(350).lte(600); //構建價格range查詢
//進行關系“與”查詢
boolQueryBuilder.must(termQueryIsReady).must(rangeQueryBuilder);
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);  //設置查詢

SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

 

2.should查詢

當查詢中包含should查詢時,表示當前查詢為“或”查詢。命中的文檔可以匹配該查詢中的一個或多個子查詢的結果,並且ES會將該查詢與文檔的匹配程度加入總得分里。should查詢包含一個數組,可以把其他的term級別的查詢及布爾查詢放入其中。

示例:

GET /hotel/_search 
{ 
  "query": { 
    "bool": { 
      "should": [                  //shoud查詢,數組內可封裝各類子查詢 
        {                          //第一個子查詢:城市為北京 
          "term": { 
            "city": { 
              "value": "北京" 
            } 
          } 
        }, 
        {                          //第二個子查詢:城市為天津 
          "term": { 
            "city": { 
              "value": "天津" 
            } 
          } 
        } 
      ] 
    } 
  } 
} 

在Java客戶端上構建should搜索時,可以使用QueryBuilders.boolQuery().should()進行構建,上面的例子改寫成Java客戶端請求的形式為:

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//構建城市為“北京”的term查詢
TermQueryBuilder termQueryIsReady = QueryBuilders.termQuery("city", "北京");
//構建城市為“上海”的term查詢
TermQueryBuilder termQueryWritter = QueryBuilders.termQuery("city", "上海");
//進行關系“或”查詢
boolQueryBuilder.should(termQueryIsReady).should(termQueryWritter);
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);   //設置查詢
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

3.must not查詢

當查詢中包含must not查詢時,表示當前查詢為“非”查詢。命中的文檔不能匹配該查詢中的一個或多個子查詢的結果,ES會將該查詢與文檔的匹配程度加入總得分里。must not查詢包含一個數組,可以把其他term級別的查詢及布爾查詢放入其中。

示例:

GET /hotel/_search 
{ 
  "query": { 
    "bool": { 
      "must_not": [                  // must_not查詢,數組內可封裝各類子查詢 
        {                            //第一個子查詢:城市為北京 
          "term": { 
            "city": { 
              "value": "北京" 
            } 
          } 
        }, 
        {                           //第二個子查詢:城市為天津 
          "term": { 
         "city": { 
              "value": "天津" 
            } 
          } 
        } 
      ] 
    } 
  } 
} 

在Java客戶端上構建must_not搜索時,可以使用QueryBuilders.boolQuery().mustNot()方法進行構建,上面的例子改寫成Java客戶端請求的形式為:

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//構建城市為“北京”的term查詢
TermQueryBuilder termQueryIsReady = QueryBuilders.termQuery("city", "北京");
//構建城市為“天津”的term查詢
TermQueryBuilder termQueryWritter = QueryBuilders.termQuery("city", "天津");
//進行關系“必須不”查詢
boolQueryBuilder.mustNot(termQueryIsReady).mustNot(termQueryWritter);
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);     //設置查詢
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

4.filter查詢

filter查詢即過濾查詢,該查詢是布爾查詢里非常獨特的一種查詢。其他布爾查詢關注的是查詢條件和文檔的匹配程度,並按照匹配程度進行打分;而filter查詢關注的是查詢條件和文檔是否匹配,不進行相關的打分計算,但是會對部分匹配結果進行緩存。

示例:

GET /hotel/_search 
{ 
  "query": { 
    "bool": { 
      "filter": [            // filter查詢,數組內可封裝各類子查詢 
        {                    //第一個子查詢:城市為北京 
          "term": { 
            "city": "北京" 
          } 
        }, 
        {                    //第一個子查詢:滿房狀態為否 
          "term": { 
            "full_room": false 
          } 
        } 
      ] 
    } 
  } 
}

在Java客戶端上構建filter搜索時,可以使用QueryBuilders.boolQuery().filter()進行構建,上面的例子改寫成Java客戶端請求的形式為:

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.filter(QueryBuilders.termQuery("city", "青島"));
boolQueryBuilder.filter(QueryBuilders.termQuery("full_room", true));
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

使用filter查詢的子句是不計算分數的,這可以減少不小的時間開銷。

為提升查詢效率,對於簡單的term級別匹配查詢,應該根據自己的實際業務場景選擇合適的查詢語句,需要確定這些查詢項是否都需要進行打分操作,如果某些匹配條件不需要打分操作的話,那么應該把這些查詢全部改成filter形式,讓查詢更高效。 

 

 

文章來源:Elasticsearch搜索引擎構建入門與實戰 --> 4.2.3 布爾查詢

 


免責聲明!

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



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