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 布尔查询

原文地址:https://www.cnblogs.com/ooo0/p/15656682.html