忽略聚合查询中的“匹配”子句

时间:2019-04-08 07:50:04

标签: elasticsearch

我有一个带有聚合的查询。聚合之一在字段starsCount上。有一个查询子句会与其他match子句(为清楚起见而被隐藏)一起过滤starsCount字段。

我希望starsCount聚合在其结果中忽略starsCount过滤(聚合的结果应该就像我在starsCount上运行了不带match子句的相同查询一样字段),而另一个聚合保持其当前行为

这可以在单个查询中完成还是应该使用多个?

以下是(简化的)查询:

{
    [...]
    "aggs": {
        "group_by_service": {
            "comment": "keep current behaviour",
            "terms": {
                "field": "services",
                "size": 46
            }
        },
        "group_by_stars": {
            "comment": "ignore the filter on the starsCount field",
            "terms": {
                "field": "starsCount",
                "size": 100
            }
        }
    },
    "query": {
        "bool": {
            "must": [
                [...] filters on other properties, non-relevant 
                {
                    "match": {
                        "starsCount": {
                            "query": "2"
                        }
                    }
                }
            ]
        }
    }
}

1 个答案:

答案 0 :(得分:1)

是的,您可以通过使用post filterfilter aggregation在单个查询中实现。 您需要按照以下步骤创建查询:

  1. 从主查询中删除starsCount匹配查询,因为它不会影响group_by_stars聚合。
  2. 由于starsCount匹配查询应过滤文档,因此将其移至post_filter。计算聚合后,post_filter内部的任何查询都将过滤文档。
  3. 现在,由于starsCount不再是主查询的一部分,因此所有聚合都不会受到它的影响。但是所需的是,此过滤器应影响除group_by_stars聚合之外的所有其他聚合。为此,我们将使用过滤器聚合并将其应用于除group_by_stars聚合之外的所有聚合。

结果查询如下。 (请注意,我使用match查询代替了term查询。您仍然可以使用match,但是在这种情况下,术语是一个更好的选择。):

{
  "aggs": {
    "some_other_agg":{
      "filter": {
        "term": {
          "starsCount": "2"
        }
      },
      "aggs": {
        "some_other_agg_filtered": {
          "terms": {
            "field": "some_other_field"
          }
        }
      }
    },
    "group_by_service": {
      "filter": {
        "term": {
          "starsCount": "2"
        }
      },
      "aggs": {
        "group_by_service_filtered": {
          "terms": {
            "field": "services",
            "size": 46
          }
        }
      }
    },
    "group_by_stars": {
      "terms": {
        "field": "starsCount",
        "size": 100
      }
    }
  },
  "query": {
    "bool": {
      "must": [
        {...} //filter on other properties
      ]
    }
  },
  "post_filter": {
    "term": {
      "starsCount": "2"
    }
  }
}