我有这个要按name
分组的模拟数据,然后有一个total
字段,它是value
字段的总和 (如果状态为是won
。
[{
name: 'Foo',
value: 12,
status: 'won'
},
{
name: 'Foo',
value: 2,
status: 'lost'
},
{
name: 'Foo',
value: 10,
status: 'won'
},
{
name: 'Bar',
value: 4,
status: 'won'
}]
我能够按名称分组并获得值字段的总和,但还没有弄清楚如何仅对获胜案例进行求和。
aggs: {
by_name: {
terms: {
field: 'name'
},
aggs: {
total_value: {
sum: {
field: 'value' // What I want is value if status == 'won'
}
}
}
}
我想要的结果应如下所示:
[{
name: 'Foo',
total_value: 22 // Currently 24
}, {
name: 'Bar',
total_value: 4
}]
这似乎是一个常用的情况,但是虽然我发现了很多有关过滤的信息,但不是这个特殊情况。
答案 0 :(得分:1)
好的,我发现了两种方法。
ES支持各种脚本语言,但是内置了对Painless的支持:
aggs: {
by_name: {
terms: {
field: 'name'
},
aggs: {
total_value: {
sum: {
script: {
lang: 'painless',
source:doc['status'].value == 'won' ? doc['value'] : 0"
}
}
}
}
}
在我的用例中,我还需要将所有的获胜和失利总计为单个字段,以获得更像是的结果集:
[{
name: 'Foo',
total_won_value: 22,
total_won: 2
total_lost_value: 2,
total_lost: 1
}, {
...
}
虽然我可以用一些脚本来完成此操作(尽管这必须进行测试),但我怀疑它可以通过嵌套聚合实现更高的性能。
aggs: {
by_name: {
terms: {
field: 'name'
},
aggs: {
by_status: {
terms: {
field: 'status'
},
aggs: {
total_value_by_status: {
sum: {
field: 'value'
}
}
}
}
}
}
}
第二种方法的缺点在于,它很难解析结果,尤其是在诸如AppSync模板之类的结果中。