有没有办法按聚合进行分组并获取属于特定组聚合的所有文档?
所以这不像聚合分组,对于每个组,您获得一些聚合/度量,但我也希望在一个查询中导致特定组聚合的所有记录。今天ES有可能吗?
例如:
输入数据集
{"name": "foo", "amount": 5, "city":"san francisco", "state": "CA"}
{"name": "foo", "amount": 10, "city":"Los angeles", "state": "CA"}
{"name": "bar", "amount": 20, "city":"Austin", "state": "TX"}
现在说我想按名称和状态进行分组,并获得每个组的“金额”和计数的总和以及导致汇总结果的记录本身。所以预期的输出是这样的
预期产出:
[
{group: {"name": "foo", "state": "CA"}, "amount": 15, "count": 2, "docs": [{"name": "foo", "amount": 5, "city":"san francisco", "state": "CA"}, {"name": "foo", "amount": 10, "city":"Los angeles", "state": "CA"}]},
{group: {"name": "bar", "state": "TX"}, "amount": 20, "count": 1, "docs": [{"name": "bar", "amount": 20, "city":"Austin", "state": "TX"}]}
]
ES 5.0很好。
答案 0 :(得分:1)
您可以使用子聚合的组合来按指标获取所有组,但尝试获取作为聚合的一部分返回的匹配是一个坏主意。对于您正在进行分组的N个文档,您基本上要求Elasticsearch返回每个文档,这些文档首先会破坏聚合的目的。
您正在“分组”的每个字段(在ES术语中,术语聚合)需要是它自己的聚合,但您可以无限地嵌套它们,并根据您定义的分组数量以编程方式序列化和反序列化结果。确保您的字词字段是“关键字”类型!
此查询将为您提供所需的所有指标 - 您只需要展平结果应用程序端:
{
"aggs" : {
"by_name" : {
"terms" : { "field" : "name" },
"aggs" : {
"by_state" : {
"terms" : { "field" : "state" },
"aggs" : {
"total_amount" : { "sum" : { "field" : "amount" } }
}
}
}
}
}
}
如果您确实需要这些文档,是否可以使用术语过滤器动态加载它们?或者,如果确实需要破解它并且您了解数据的分布,则可以使用top_hits sub aggregation返回文档。请注意,每个额外的子聚合,尤其是热门命中,都会影响性能。