在 Spring 数据 Elasticsearch 中创建嵌套查询

Creating Nested Query in Spring Data Elasticsearch

我是 Spring Data Elasticsearch 的新手,正在尝试构建如下所示的查询; 任何帮助将不胜感激。

 {
   "query":{
      "bool":{
         "must":[
            {
               "bool":{
                  "should":[
                     {
                        "match_phrase":{
                           "firstPhrase":"A"
                        }
                     },
                     {
                        "match_phrase":{
                           "secondPhrase":"B"
                        }
                     },
                     {
                        "nested":{
                           "path":"things",
                           "query":{
                              "bool":{
                                 "should":[
                                    {
                                       "match_phrase":{
                                          "another.phraseOne":"C"
                                       }
                                    },
                                    {
                                       "match_phrase":{
                                          "another.phraseTwo":"D"
                                       }
                                    }
                                 ]
                              }
                           }
                        }
                     }
                  ]
               }
            },
            {
               "match_phrase":{
                  "otherPhase":"E"
               }
            }
         ]
      }
   }
}

我开始创建前两个布尔查询;

BoolQueryBuilder firstBool = QueryBuilders.boolQuery()
                .should(QueryBuilders.matchPhraseQuery("firstPhrase", "A"))
                .should(QueryBuilders.matchPhraseQuery("secondPhrase", "B"));

BoolQueryBuilder secondBool = QueryBuilders.boolQuery()
                .should(QueryBuilders.matchPhraseQuery("another.phraseOne", "C"))
                .should(QueryBuilders.matchPhraseQuery("another.phraseTwo", "D"));

然后我尝试创建一个嵌套查询(不确定如何使用 ScoreMode);

 QueryBuilder nestedQuery= nestedQuery("things",secondBool, ScoreMode.None);

我又创造了一个必须的匹配短语;

 QueryBuilder third = QueryBuilders.matchPhraseQuery("otherPhrase", "E");

我不确定如何将它们全部添加以创建我拥有的结构,最重要的是不确定如何将嵌套查询添加到“必须”。

  QueryBuilder allQueries = new BoolQueryBuilder()
            .must(first)
            .must(second)
            .must(third); 

最后,一次性使用它们;

NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(allQueries).build();

这是实现我想要生成的目标的正确方法吗?

您几乎成功了,重新排列查询构建的顺序:

import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;

class Scratch {
    public static void main(String[] args) {

        BoolQueryBuilder boolShouldCD = QueryBuilders.boolQuery()
                .should(QueryBuilders.matchPhraseQuery("another.phraseOne", "C"))
                .should(QueryBuilders.matchPhraseQuery("another.phraseTwo", "D"));

        QueryBuilder nestedQuery= QueryBuilders.nestedQuery("things",boolShouldCD, ScoreMode.None);

        BoolQueryBuilder boolShouldABNested = QueryBuilders.boolQuery()
                .should(QueryBuilders.matchPhraseQuery("firstPhrase", "A"))
                .should(QueryBuilders.matchPhraseQuery("secondPhrase", "B"))
                .should(nestedQuery);

        QueryBuilder allQueries = new BoolQueryBuilder()
                .must(boolShouldABNested)
                .must(QueryBuilders.matchPhraseQuery("otherPhrase", "E"));

        System.out.println(allQueries.toString());
    }
}

这是普通的 Elasticsearch 客户端代码,要在 Spring Data Elasticsearch 中使用它,使用 NativeSearchQueryBuilder 是正确的方法。


在内联和静态导入之后,您会得到这个更短的代码:

import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;

import static org.elasticsearch.index.query.QueryBuilders.*;

class Scratch {
    public static void main(String[] args) {

        QueryBuilder allQueries = new BoolQueryBuilder()
                .must(boolQuery()
                        .should(matchPhraseQuery("firstPhrase", "A"))
                        .should(matchPhraseQuery("secondPhrase", "B"))
                        .should(nestedQuery("things", boolQuery()
                                .should(matchPhraseQuery("another.phraseOne", "C"))
                                .should(matchPhraseQuery("another.phraseTwo", "D")), ScoreMode.None)))
                .must(matchPhraseQuery("otherPhrase", "E"));

        System.out.println(allQueries.toString());
    }
}