Elasticsearch Java高级Rest Client构造具有多个匹配值和OR条件的布尔查询

时间:2019-10-17 15:11:18

标签: java elasticsearch elasticsearch-java-api elasticsearch-query

我试图通过Java高级Rest客户端构造一个查询,该客户端实现ID列表并使用OR运算符返回与WHERE子句类似的所有与给定ID匹配的文档。

由于这个原因,我一直在进行布尔查询,并尝试对列表进行迭代,并且必须将运算符设置为OR的每个值都匹配

BoolQueryBuilder builder = QueryBuilders.boolQuery();
ids.forEach(i -> {
     bool.must(QueryBuilders.matchQuery("_id", i).operator(Operator.OR));
});

return bool;

//这样就构造了dsl

{
  "bool" : {
    "must" : [
      {
        "match" : {
          "_id" : {
            "query" : "0025370c-baea-4dcc-af48-56c4bdb86854",
            "operator" : "OR",
            "prefix_length" : 0,
            "max_expansions" : 50,
            "fuzzy_transpositions" : true,
            "lenient" : false,
            "zero_terms_query" : "NONE",
            "auto_generate_synonyms_phrase_query" : true,
            "boost" : 1.0
          }
        }
      },
      {
        "match" : {
          "_id" : {
            "query" : "013fedef-6b04-4520-8458-fca8b0366833",
            "operator" : "OR",
            "prefix_length" : 0,
            "max_expansions" : 50,
            "fuzzy_transpositions" : true,
            "lenient" : false,
            "zero_terms_query" : "NONE",
            "auto_generate_synonyms_phrase_query" : true,
            "boost" : 1.0
          }
        }
      },
      {
        "match" : {
          "_id" : {
            "query" : "01c44ce4-0e87-4dc9-8a29-1f24679d335f",
            "operator" : "OR",
            "prefix_length" : 0,
            "max_expansions" : 50,
            "fuzzy_transpositions" : true,
            "lenient" : false,
            "zero_terms_query" : "NONE",
            "auto_generate_synonyms_phrase_query" : true,
            "boost" : 1.0
          }
        }
      }
    ],
    "adjust_pure_negative" : true,
    "boost" : 1.0
  }
}

仅能正常工作的

无效,因为我认为OR嵌套到低位,并且不会应用于多个匹配项。因此,我认为需要有一个嵌套类型,并且我尝试了以下方法:

BoolQueryBuilder bool = QueryBuilders.boolQuery();
BoolQueryBuilder subBool = QueryBuilders.boolQuery();
ids.forEach(i -> {
     subBool.must(QueryBuilders.matchQuery("_id", i).operator(Operator.OR));
});

bool.must(subBool);

return bool;

//对我来说,将操作员条件放在bool而不是subBool上会更有意义,但它不可用,并且我确定我会错了

{
  "bool" : {
    "must" : [
      {
        "bool" : {
          "must" : [
            {
              "match" : {
                "_id" : {
                  "query" : "0025370c-baea-4dcc-af48-56c4bdb86854",
                  "operator" : "OR",
                  "prefix_length" : 0,
                  "max_expansions" : 50,
                  "fuzzy_transpositions" : true,
                  "lenient" : false,
                  "zero_terms_query" : "NONE",
                  "auto_generate_synonyms_phrase_query" : true,
                  "boost" : 1.0
                }
              }
            },
            {
              "match" : {
                "_id" : {
                  "query" : "013fedef-6b04-4520-8458-fca8b0366833",
                  "operator" : "OR",
                  "prefix_length" : 0,
                  "max_expansions" : 50,
                  "fuzzy_transpositions" : true,
                  "lenient" : false,
                  "zero_terms_query" : "NONE",
                  "auto_generate_synonyms_phrase_query" : true,
                  "boost" : 1.0
                }
              }
            },
            {
              "match" : {
                "_id" : {
                  "query" : "01c44ce4-0e87-4dc9-8a29-1f24679d335f",
                  "operator" : "OR",
                  "prefix_length" : 0,
                  "max_expansions" : 50,
                  "fuzzy_transpositions" : true,
                  "lenient" : false,
                  "zero_terms_query" : "NONE",
                  "auto_generate_synonyms_phrase_query" : true,
                  "boost" : 1.0
                }
              }
            }
          ],
          "adjust_pure_negative" : true,
          "boost" : 1.0
        }
      }
    ],
    "adjust_pure_negative" : true,
    "boost" : 1.0
  }
}

如果我在嵌套匹配中将其减少为单个值(还是用1个id代替很多),这似乎是可行的...所以我仍然认为我实现的OR条件错误。

布尔查询中的过滤器而不是必须匹配的过滤器会产生相同的结果。感谢帮助。

1 个答案:

答案 0 :(得分:2)

IFERROR查询中的OR运算符意味着该特定子查询的每个查询字符串中只有一个术语必须与文档匹配才能使子查询匹配,所以这不是您的目标。要将子查询与match进行复合,您必须在根布尔查询中使用OR而不是shouldmustmust运算符的ElasticSearch等效项,而AND表示should