【问题标题】:Elasticsearch - aggregation of unique countsElasticsearch - 唯一计数的聚合
【发布时间】:2016-08-21 03:31:31
【问题描述】:

我有一个 Elasticsearch 图书数据库:

{
  "id": 1,
  "name": "Animal Farm"
},
{
  "id": 2,
  "name": "Brave New World"
},
{
  "id": 3,
  "name": "Nineteen Eighty-Four"
},
{
  "id": 4,
  "name": "Animal Farm"
},
{
  "id": 5,
  "name": "We"
}

如您所见,14 中带有id 的书有冲突书名“Animal Farm”。但是,它们是不同的书。一个是乔治奥威尔的,另一个是关于农场动物的。

我想知道书名冲突的频率。对于上面的例子,预期的结果是:

{
  "conflicts": [
    {
      "num_of_books": 2,
      "count": "1"
    },
    {
      "num_of_books": 1,
      "count": "3"
    }
  ]
}

2num_of_books的条目是“动物农场”的冲突,并且发生过一次(因此count1)。其他 3 本书的名称各不相同,因此它们以 num_of_books1count3 出现在条目中。我不需要书名。只有数量很重要。

我知道 SQL 有“子查询”来执行此操作:

SELECT num_of_books, COUNT(*) AS _count
FROM (
  SELECT COUNT(*) AS num_of_books
  FROM books
  GROUP BY name
)
GROUP BY num_of_books;

看了Nested AggregationSub-Aggregations的文章,没看到实现目标的可能性。

任何评论都会有所帮助,谢谢!

【问题讨论】:

    标签: elasticsearch subquery aggregation


    【解决方案1】:

    据我所知,在 ES 中还不可能在聚合上运行聚合。我知道一些关于允许对桶聚合结果应用额外逻辑的突出问题,但它们仍在讨论和辩论中。

    在您的情况下,您可以通过使用 terms 聚合来摆脱内部 SQL 查询,以便使用 min_doc_count: 2 获取所有冲突书籍的名称。

    {
        "size": 0,
        "aggs": {
            "books": {
                "terms": {
                    "field": "name",
                    "min_doc_count": 2
                }
            }
        }
    }
    

    然后您可以在客户端解析存储桶并根据其数量将它们重新存储到新的num_of_books 存储桶中。例如,使用 head 插件,您可以在 Transform 部分添加以下代码

    var num_of_books = {};
    root.aggregations.books.buckets.forEach(function(b) {
        num_of_books[b.doc_count] = (num_of_books[b.doc_count] || 0) + 1;
    });
    return num_of_books;
    

    num_of_books 将包含如下内容:

    {
        "2": 1,
        "1": 3
    }
    

    【讨论】:

    • 感谢您的回答,但数据量不允许我在客户端进行外部聚合。有没有办法在服务器上进行所有计算?喜欢使用脚本字段?
    • 对于初学者,您是否尝试过我的建议只是为了看看性能会产生什么?使用 head 插件,您可以在不到一分钟的时间内检查它的工作原理。
    • 是的,我尝试了您的解决方案,但我的客户等待它的时间太长了。我需要在 10 秒内完成计算。
    • 有什么方法可以预先计算内部聚合并将其存储在另一个索引中,您将在该索引上运行外部聚合?您的图书索引多久更改一次?
    • 我可以将内部聚合的结果存储在一些临时索引中而不让客户端下载结果(即所有操作都在服务器端完成)吗?
    猜你喜欢
    • 2019-10-09
    • 2015-12-11
    • 2016-03-13
    • 2017-01-28
    • 1970-01-01
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多