使用ES查询语句的时候 会遇到嵌套多条件查询情况
- title或者content包含xx(should)
- type必须是1(must)
- enabled必须是1(must_not)
只使用should查询
GET _search
{
"query": {
"bool": {
"should": [
{
"match_phrase": {
"title": "疫情期间"
}
},
{
"match_phrase": {
"content": "疫情期间"
}
}
],
"must_not": [
{
"match": {
"enabled": 0
}
}
]
}
},
"highlight": {
"pre_tags": [
"<font color='red'>"
],
"post_tags": [
"</font>"
],
"fields": {
"title": {},
"content": {}
}
}
}
如果直接使用查询语句 会发现 查询出的结果 只满足must条件 should失效了
GET _search
{
"query": {
"bool": {
"should": [
{
"match_phrase": {
"title": "疫情期间"
}
},
{
"match_phrase": {
"content": "疫情期间"
}
}
],
"must": [
{"match": {
"type": "1"
}}
],
"must_not": [
{
"match": {
"enabled": 0
}
}
]
}
},
"highlight": {
"pre_tags": [
"<font color='red'>"
],
"post_tags": [
"</font>"
],
"fields": {
"title": {},
"content": {}
}
}
}
最终结果
使用多个must嵌套查询 将should组成的bool查询包含在其中一个must查询中
GET _search
{
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"match_phrase": {
"title": "疫情期间"
}
},
{
"match_phrase": {
"content": "疫情期间"
}
}
]
}
},
{
"match": {
"type": "1"
}
}
],
"must_not": [
{
"match": {
"enabled": 0
}
}
]
}
},
"highlight": {
"pre_tags": [
"<font color='red'>"
],
"post_tags": [
"</font>"
],
"fields": {
"title": {},
"content": {}
}
}
}
Java代码
@Override
public CommonResult<?> search(String keyword, Integer type, Integer pageNum, Integer pageSize) {
// 处理分页逻辑
pageNum = Optional.ofNullable(pageNum).orElse(1);
pageSize = Optional.ofNullable(pageSize).orElse(10);
// 设置代码高亮
String preTag = "<font color='#dd4b39'>";
String postTag = "</font>";
// 创建查询语句 ES中must和should不能同时使用 同时使用should失效 嵌套多个must 将should条件拼接在一个must中即可
BoolQueryBuilder shouldQuery = QueryBuilders.boolQuery()
.should(QueryBuilders.matchPhraseQuery("title", keyword))
.should(QueryBuilders.matchPhraseQuery("content", keyword));
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
.must(shouldQuery)
.mustNot(QueryBuilders.matchQuery("enabled", 0));
if (!ObjectUtils.isEmpty(type) && type > 0 && type < 9) {
boolQueryBuilder.must(QueryBuilders.matchQuery("type", type));
}
// 封装查询
NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder()
.withQuery(boolQueryBuilder)
.withPageable(PageRequest.of(Math.max(pageNum - 1, 0), pageSize))
.withHighlightFields(new HighlightBuilder.Field("title").preTags(preTag).postTags(postTag),
new HighlightBuilder.Field("content").preTags(preTag).postTags(postTag));
// 进行查询操作
AggregatedPage<SearchMainPageEntity> pages = mRestTemplate.queryForPage(builder.build(), SearchMainPageEntity.class, new CustomEsResultMapper());
Object resultInfo = CustomEsResultMapper.inflatePageInfo(pages);
return successBody(resultInfo);
}