首页 > 解决方案 > 如何在 Elasticsearch 中对同一文档进行最大日期聚合?

问题描述

我有数以百万计的文档,其中包含这样的块:

{
  "useraccountid": 123456,
  "purchases_history" : {
    "last_updated" : "Sat Apr 27 13:41:46 UTC 2019",
    "purchases" : [
      {
        "purchase_id" : 19854284,
        "purchase_date" : "Jan 11, 2017 7:53:35 PM"
      },
      {
        "purchase_id" : 19854285,
        "purchase_date" : "Jan 12, 2017 7:53:35 PM"
      },
      {
        "purchase_id" : 19854286,
        "purchase_date" : "Jan 13, 2017 7:53:35 PM"
      }
    ]
  }
}

我想弄清楚我怎么能做这样的事情:

SELECT useraccountid, max(purchases_history.purchases.purchase_date) FROM my_index GROUP BY useraccountid

我只找到了最大聚合,但它聚合了索引中的所有文档,但这不是我需要的。我需要找到每个文件的最大购买日期。我相信必须有一种方法可以遍历每个文档的每条路径purchase_history.purchases.purchase_date以确定哪一个是最大购买日期,但我真的找不到怎么做(如果这确实是最好的方法) .

有什么建议吗?

标签: elasticsearch

解决方案


我假设你的领域useraccountid是独一无二的。你将不得不做一个术语聚合,里面做最大聚合。我能想到这个:

"aggs":{
    "unique_user_ids":{
        "terms":{
            "field": "useraccountid",
            "size": 10000 #Default value is 10
        },
        "aggs":{
            "max_date":{
                "max":{
                    "field": "purchases_history.purchases.purchase_date"
                }
            }
        }
    }
}

在该aggregations字段中,您将首先看到唯一的用户 ID,然后在里面看到他们的最大日期。

请注意大小中的 10,000。terms仅建议聚合返回 10,000 个结果。

如果您需要更多,可以使用Composite 聚合。这样,您可以对结果进行分页,并且您的集群不会出现性能问题。

如果您想使用 Composite,我可以想到以下几点:

GET /_search
{
    "aggs" : {
        "my_buckets": {
            "composite" : {
                "size": 10000, #Default set to 10
                "sources" : [
                    { "user_id": { "terms": {"field": "useraccountid" } } },
                    { "product": { "max": { "field": "purchases_history.purchases.purchase_date" } } }
                ]
            }
        }
    }
}

运行查询后,它将返回一个名为after_key. 使用该字段,您可以在 10,000 个元素的页面中对结果进行分页。查看复合聚合的 After 参数

希望这有帮助!:D


推荐阅读