我是ES的菜鸟,我不知道如何解决这个简单的场景:
dataType value 1 A 1 A 1 B 2 B 3 A 3 A 4 A 4 B
我需要知道有多少数据类型只有' A'价值,有多少人只有' B'价值,以及有多少。此示例的预期结果是:
Only A = 1 (dataType 3)
Only B = 1 (dataType 2)
Both = 2 (dataTypes 1 and 4)
Only A = 1 (dataType 3)
Only B = 1 (dataType 2)
Both = 2 (dataTypes 1 and 4)
ChintanShah25嗨,非常感谢您的快速回复。我尝试了你开发的代码,但似乎没有正常工作:
"Aggregations": {
"Datatypes": {
"Value": {
"Both": 0,
"Onlya": 1,
"OnlyB": 1
}
}
}
如果我删除" reduce_script"我可以调试,获得:
"Aggregations": { "Datatypes": { "Value": [ [ [ "1" ], [] ], [ [] [] ], [ [ "1" ], [ "1", "2" ] ], [ [ "4" ], [] ], [ [ "3" ], [ "4" ] ] ] } }
数据类型被正确分组,但似乎它们被分成不同的桶或锐利,最后一步是" reduce_script"失败。
文档"脚本度量标准"很差,虽然测试没有达到预期的效果。
问候。
答案 0 :(得分:2)
我想这很棘手,可以由scripted metric aggregation来完成。我创建了一个测试索引并插入了您提供的示例数据。以下查询提供了您想要的结果
{
"query": {
"match_all": {}
},
"aggs": {
"Datatypes": {
"scripted_metric": {
"init_script": "_agg['onlya'] = [];_agg['onlyb'] = [];",
"map_script": "if (doc['value'].value == \"A\")
{ _agg.onlya.add(doc['datatype'].value) };
if (doc['value'].value == \"B\")
{ _agg.onlyb.add(doc['datatype'].value) };",
"combine_script": "onlya = _agg['onlya'].unique();
onlyb = _agg['onlyb'].unique();
return[onlya, onlyb]",
"reduce_script": "both_bucket=[];a_bucket=[];b_bucket=[];
for(a in _aggs)
{both_bucket=a[0].intersect(a[1]);
a_bucket=a[0]-a[1];
b_bucket=a[1]-a[0]};
return ['Both' : both_bucket.size(),
'OnlyA' : a_bucket.size(),
'OnlyB' : b_bucket.size()];"
}
}
},
"size": 0
}
这是我得到的输出
"aggregations": {
"Datatypes": {
"value": {
"Both": 2,
"OnlyA": 1,
"OnlyB": 1
}
}
}
您需要enable dynamic scripting才能使用此功能或将这些脚本放在scripts folder中。
在 init_script 期间,我声明了两个将保存 datatype 值的变量。
map_script 遍历每个文档,并将数据类型添加到 onlya ,如果值为" A"或者 onlyb 。如果您确定要有A或B
,则可以用else替换第二个if combine_script 将列表转换为唯一值,以便[1,1,3,3,4]
变为[1,3,4]
reduce_script 从所有分片中获取结果。 交集会为您提供包含数据类型值和减法的存储区,只会为您提供 部分。size()
为您提供列表的长度。删除size方法以获取匹配的数据类型值。
请浏览documentation以了解有关所有这些不同聚合阶段的工作原理的更多信息
答案 1 :(得分:0)
我最终让它按照我的意愿工作。非常感谢你的帮助。
"aggs": {
"Datatypes": {
"scripted_metric": {
"init_script": "_agg['onlya'] = [];_agg['onlyb'] = [];",
"map_script": "valueAdd=doc['datatype'].value; if (doc['value'].value == \"a\") { _agg['onlya'].add(valueAdd) }; if (doc['value'].value == \"b\") { _agg['onlyb'].add(valueAdd) };",
"combine_script": "onlya = _agg['onlya'].unique(); onlyb = _agg['onlyb'].unique(); return[onlya, onlyb]",
"reduce_script": "a_bucket=[];b_bucket=[];for(a in _aggs){ a_bucket+=a[0]; b_bucket+=a[1];}; return ['Both' : a_bucket.intersect(b_bucket).size(), 'OnlyA' : (a_bucket-b_bucket).size(), 'OnlyB' : (b_bucket-a_bucket).size()];"
}
}
}