您可以将scripted_metric aggregation 与无痛脚本一起使用
查询
下面我会详细解释。
POST index/type/_search
{
"size": 0,
"aggs": {
"colorgroups": {
"scripted_metric": {
"init_script" : "params._agg.transactions = [:]",
"map_script": "params.key = doc['colorname'].value; if(params._agg.transactions[params.key] == null){ params._agg.transactions[params.key] = 1; }else{ params._agg.transactions[params.key] ++ }",
"combine_script": "return params._agg.transactions;",
"reduce_script": "params.color_counters =[:]; params.groups_counters =[:]; for(shard_result in params._aggs){ for(color_name in shard_result.keySet()){ if(params.color_counters[color_name] == null){ params.color_counters[color_name] = shard_result[color_name] }else{ params.color_counters[color_name] = params.color_counters[color_name] + shard_result[color_name] } } } for(color_name in params.color_counters.keySet()){ params.group_counter = params.color_counters[color_name].toString(); if(params.groups_counters[params.group_counter] == null){ params.groups_counters[params.group_counter] = 1 }else{ params.groups_counters[params.group_counter] ++ } } return params.groups_counters"
}
}
}
}
结果
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 9,
"max_score": 0,
"hits": []
},
"aggregations": {
"colorgroups": {
"value": {
"2": 3,
"1": 2,
"1": 1
}
}
}
}
init_script
初始化一些值以保留中间结果
params._agg.transactions = [:]
地图脚本
每个文档的计算。在这一步尽量保持小并减少尽可能多的数据。
params.key = doc['colorname'].value;
if(params._agg.transactions[params.key] == null){
params._agg.transactions[params.key] = 1;
}else{
params._agg.transactions[params.key] ++
}
combine_script
每个分片的计算。我们已经在 map_script 中做了所有事情,只需返回 hash map
return params._agg.transactions
reduce_script
使用来自每个分片的部分聚合。我们需要先将它们合并到一个 HashMap 中。然后按计数器值分组
params.color_counters =[:];
params.groups_counters =[:];
//merging all partial aggregations to params.color_counters
for(shard_result in params._aggs){
for(color_name in shard_result.keySet()){
if(params.color_counters[color_name] == null){
params.color_counters[color_name] = shard_result[color_name]
}else{
params.color_counters[color_name] = params.color_counters[color_name] + shard_result[color_name]
}
}
}
//Grouping by color counter to params.groups_counters
for(color_name in params.color_counters.keySet()){
params.group_counter = params.color_counters[color_name].toString();
if(params.groups_counters[params.group_counter] == null){
params.groups_counters[params.group_counter] = 1
}else{
params.groups_counters[params.group_counter] ++
}
}
return params.groups_counters
你可以打电话
Debug.explain(variable);
在无痛脚本中的任何位置调试变量并根据需要调整脚本。