【问题标题】:Elasticsearch bool query formation with multiple must clause具有多个必须子句的 Elasticsearch bool 查询形式
【发布时间】:2017-08-17 13:40:55
【问题描述】:

我有如下查询 -

 {
    "query": {
        "bool": {
            "must": {
                "bool" : { "should": [
                      { "match": { "camp_id": "Elasticsearch" }},
                      { "match": { "camp_id": "Solr" }} ] }
            },
            "must": { 
                "bool" : { "should": [
                      { "match": { "ad_id": "Elastic" }},
                      { "match": { "ad_id": "dummy" }} ] }
            },
            "must_not": { "match": {"authors": "radu gheorge" }},
            .....
            .....     
        }
    }
    }

简而言之,(camp_id = 'elasticsearch' or camp_id = 'solr') AND (ad_id = 'elasticsearch' or ad_id = 'solr') ....

经过大量研究,我编写了以下java代码 -

    final SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

    final BoolQueryBuilder finalBoolQuery = new BoolQueryBuilder();

    BoolQueryBuilder campaignBoolQuery = null;
    if (campaignIds != null) {
        campaignBoolQuery = QueryBuilders.boolQuery();
        for (int campaignId : campaignIds) {
            campaignBoolQuery.should(QueryBuilders.matchQuery("camp_id", campaignId));
        }
    }

    BoolQueryBuilder creativeBoolQuery = null;
    if (creativeIds != null) {
        creativeBoolQuery = QueryBuilders.boolQuery();
        for (int creativeId : creativeIds) {
            creativeBoolQuery.should(QueryBuilders.matchQuery("ad_id", creativeId));
        }
    }

    finalBoolQuery.must(campaignBoolQuery);
    finalBoolQuery.must(creativeBoolQuery);
    searchSourceBuilder.query(finalBoolQuery).size(9999);

    System.out.println(searchSourceBuilder.toString());

使用上面的代码,我希望我会有 1 个 must 子句用于 'camp_id',另外 1 个用于 'ad_id' 但以下是我得到的 -

    {
  "size" : 9999,
  "query" : {
    "bool" : {
      "must" : [
        {
          "bool" : {
            "should" : [
              {
                "match" : {
                  "camp_id" : {
                    "query" : 1,
                    "operator" : "OR",
                    "prefix_length" : 0,
                    "max_expansions" : 50,
                    "fuzzy_transpositions" : true,
                    "lenient" : false,
                    "zero_terms_query" : "NONE",
                    "boost" : 1.0
                  }
                }
              },
              {
                "match" : {
                  "camp_id" : {
                    "query" : 2,
                    "operator" : "OR",
                    "prefix_length" : 0,
                    "max_expansions" : 50,
                    "fuzzy_transpositions" : true,
                    "lenient" : false,
                    "zero_terms_query" : "NONE",
                    "boost" : 1.0
                  }
                }
              }
            ],
            "disable_coord" : false,
            "adjust_pure_negative" : true,
            "boost" : 1.0
          }
        },
        {
          "bool" : {
            "should" : [
              {
                "match" : {
                  "ad_id" : {
                    "query" : 1,
                    "operator" : "OR",
                    "prefix_length" : 0,
                    "max_expansions" : 50,
                    "fuzzy_transpositions" : true,
                    "lenient" : false,
                    "zero_terms_query" : "NONE",
                    "boost" : 1.0
                  }
                }
              }
            ],
            "disable_coord" : false,
            "adjust_pure_negative" : true,
            "boost" : 1.0
          }
        }
      ],
      "disable_coord" : false,
      "adjust_pure_negative" : true,
      "boost" : 1.0
    }
  }
}

只有一个包含camp_id 和ad_id 的must 子句。有人可以指出我错过了什么吗?我使用弹性搜索版本 - 5.5.0 和 jest - 2.4.0 作为我的 java 客户端。

【问题讨论】:

  • 我使用 cerebro 作为 UI 来访问 elasticsearch 集群。当我尝试从 cerebro 提供的其余客户端执行查询时,我观察到它给了我一个错误,指出 - 重复的 must 子句。是不是我们不能有多个必须子句?如果没有,应该有一种方法来处理查询,例如 SELECT * FROM campaign WHERE id IN (1,2,3) AND name IN ('a', 'b', 'c')。有人可以帮帮我吗?

标签: elasticsearch elasticsearch-jest


【解决方案1】:

您的外部 bool 示例查询包含两个 must 子句,但它必须是一个包含对象数组的 must 子句。我想你在调用must() 两次时用第二个覆盖了第一个必须子句。

【讨论】:

  • 不完全是,必须作为“和”,应该作为“或”,因此,对象:{“camp_id”:“Elasticsearch”,“ad_id”:“Elastic”}将是有效结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-16
  • 1970-01-01
相关资源
最近更新 更多