首页 > 解决方案 > 如何在术语聚合中获得所有存储桶的总计数?

问题描述

我正在使用弹性搜索terms聚合来根据每个文档上的数组属性存储桶。我想获取每个存储桶中的文档总数。

假设每个文档都是一个Post,并且具有一个数组属性,该属性media指定帖子所在的社交媒体网站(并且可能为空):

{
   id: 1
   media: ["facebook", "twitter", "instagram"]
}
{
   id: 2
   media: ["twitter", "instagram", "tiktok"]
}
{
   id: 3
   media: ["instagram"]
}
{
   id: 4
   media: []
}

这是我termsmedia.

"aggs": {
    "Posts_by_media": {
      "terms": {
        "field": "media",
        "size": 1000
      }
    }
  }
}

这将返回以下内容:

{
  ...
  "aggregations": {
    "Posts_by_media": {
      "doc_count_error_upper_bound": 0,   
      "sum_other_doc_count": 0,           
      "buckets": [                        
        {
          "key": "instagram",
          "doc_count": 3
        },
        {
          "key": "twitter",
          "doc_count": 2
        },
        {
          "key": "facebook",
          "doc_count": 1
        },
        {
          "key": "tiktok",
          "doc_count": 1
        }
      ]
    }
  }
}

除了这个结果,我还想知道这些桶中的文档总数。

如您所见,文档将针对 中的每个值计算在内media。因此,带有 的帖子将id: 1计入 和 的三个桶。facebooktwitterinstagram

因此,将每个桶计数加在一起是不够的。我会得到7,正确答案应该是3(因为文档media: []不会包含在任何存储桶中)。

有没有办法返回这些桶中的文档总数?

稍微看一下文档,似乎我可以使用另一个聚合,即存在聚合,如下所示:

{
  "aggs": {
    "filter": {
      "exists": {
        "field": "media"
      }
    }
  }
}

但是,我对这是一个单独的聚合这一事实感到不舒服——感觉如果我不小心,我可能会让两者不同步。

这里有什么建议?

标签: elasticsearch

解决方案


从你的描述中你想查询media不为空的数据个数?如果是,可以使用下面的查询。

{
  "query": {
    "bool": {
      "must": [
        {
          "exists": {
            "field": "media"
          }
        }
      ]
    }
  },
  "size": 0
}

totalfrom 响应是此查询中的命中数。

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 0,
    "max_score" : 0.0,
    "hits" : [ ]
  }
}

推荐阅读