elasticsearch - Elasticsearch:将每个嵌套元素乘以聚合
问题描述
让我们想象一个由 2 个文档组成的索引,如下所示:
doc1 = {
"x":1,
"y":[{brand:b1, value:1},
{brand:b2, value:2}]
},
doc2 = {
"x":2,
"y":[{brand:b1, value:0},
{brand:b2, value:3}]
}
是否可以将每个文档的 y 的每个值乘以 x,然后根据品牌术语进行总和聚合以获得此结果:
b1: 1
b2: 8
如果没有,是否可以使用任何其他映射类型来完成?
解决方案
这是一个高度自定义的用例,所以我认为没有某种预先优化的映射。
我建议如下:
建立一个索引 w y
/ nested
:
PUT xy/
{"mappings":{"properties":{"y":{"type":"nested"}}}}
从您的示例中提取文档:
POST xy/_doc
{"x":1,"y":[{"brand":"b1","value":1},{"brand":"b2","value":2}]}
POST xy/_doc
{"x":2,"y":[{"brand":"b1","value":0},{"brand":"b2","value":3}]}
使用scripted_metric
聚合来计算产品并将它们添加到 shared 中HashMap
:
GET xy/_search
{
"size": 0,
"aggs": {
"multiply_and_add": {
"scripted_metric": {
"init_script": "state.by_brands = [:]",
"map_script": """
def x = params._source['x'];
for (def brand_pair : params._source['y']) {
def brand = brand_pair['brand'];
def product = x * brand_pair['value'];
if (state.by_brands.containsKey(brand)) {
state.by_brands[brand] += product;
} else {
state.by_brands[brand] = product;
}
}
""",
"combine_script": "return state",
"reduce_script": "return states"
}
}
}
}
这将产生一些类似的东西
{
...
"aggregations":{
"multiply_and_add":{
"value":[
{
"by_brands":{ <----
"b2":8,
"b1":1
}
}
]
}
}
}
更新
combine_script
可能看起来像这样:
def combined_states = [:];
for (def state : states) {
for (def brand_pair : state['by_brands'].entrySet()) {
def key = brand_pair.getKey();
def value = brand_pair.getValue();
if (combined_states.containsKey(key)) {
combined_states[key] += (float)value;
break;
}
combined_states[key] = (float)value
}
}
推荐阅读
- java - 如何用流替换两个嵌套的for循环和if语句
- angularjs - 如何在控制器范围内调用更改事件?
- python - django DateField 中 Xlswriter 的输出不正确
- ios - 如何快速发出http请求?(错误:在 json 上)
- java - 根据条目字段为所有条目在榛树中设置 TTL/记录到期
- python - 检测后如何从图像中提取文本区域
- python - Pandas:从作为列值拆分的 ID 获取行
- ionic-framework - 离子应用程序名称不能以数字错误开头
- c# - 数据读取器不兼容。类型的成员“RoleId”在数据读取器中没有同名的对应列
- ios - 无法分配“NSDictionary”类型的值?键入“字符串?”