错误示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| GET /hotel/_search { "query": { "bool": { "must": [ { "term": { "city": { "value": "上海" } } } ], "should": [ {"term": { "brand": { "value": "希尔顿" } }}, {"term": { "brand": { "value": "皇冠假日" } }} ] } }, "size": 100 }
|
1 2 3
| BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); boolQuery.must(QueryBuilders.termQuery("city", "上海")) .should(QueryBuilders.termsQuery("brand", "希尔顿", "皇冠假日"));
|
- 布尔查询中,使用should属性时,生效了,但没完全生效。
- 查到的结果集中包含了
上海希尔顿
和上海皇冠假日
的酒店文档,但是后面还出现了其他品牌的酒店文档
- 利用控制变量法,成功找到bug原因
- 单独使用
must
查询,没有问题
- 单独使用
should
查询,没有问题
- 联合使用
must
和should
,查询到的结果条数,与单独使用must
一样。但是排序是优先展示符合should
条件的文档
失效原因
- should在和must同时使用的时候es内部属性
minumum_should_match
默认是 0
- 单独使用should时
minumum_should_match
默认是 1
解决方案
- 方案一:为
minumum_should_match
手动赋值
1 2 3 4
| BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); boolQuery.minimumShouldMatch(1); boolQuery.must(QueryBuilders.termQuery("city", "上海")) .should(QueryBuilders.termsQuery("brand", "华美达", "皇冠假日"));
|
- 方案二:将should查询对象设置到must方法中
1 2 3
| BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); boolQuery.must(QueryBuilders.termQuery("city", "上海")) .must(QueryBuilders.termsQuery("brand", "华美达", "皇冠假日"));
|
解决ES中同时使用must和should 只有must生效的问题