在Elasticsearch中,我需要获得从最高到最低频率出现的频率和颜色数量。 如果我有这样的数据:
id|name
----------
1|blue
----------
2|blue
----------
3|green
----------
4|yellow
----------
5|blue
----------
6|yellow
----------
7|purple
----------
8|purple
----------
9|purple
我需要获取每种颜色的计数,然后按计数分组。所以最后,我希望所有出现相同次数的颜色都在一个组内。 这是我在sql中的方式。
select
count(*) as 'Number of Colors',
i.c as 'Seen times'
from
(
select
name as 'n',
count(*) as 'c'
from
colors
group by name
) i
group by i.c
order by i.c desc;
这将返回:
Number of Colors | Seen times
------------------------------
2 | 3
------------------------------
1 | 2
------------------------------
1 | 1
我如何在Elasticsearch查询中编写它?我使用的是5.5版本。
答案 0 :(得分:0)
您可以使用The "AdjustJavacVersionArguments" task failed unexpectedly无痛脚本
我将在下面详细解释。
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
}
}
}
}
初始化一些值以保持中间结果
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] ++
}
每个分片的计算。我们已经在map_script中做了所有事情,只返回哈希映射
return params._agg.transactions
使用每个分片的部分聚合。我们需要先将它们合并到一个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);
在无痛脚本中的任何地方调试变量并根据需要调整脚本。
答案 1 :(得分:0)
默认情况下,弹性搜索不提供任何使用的聚合类型 一些聚合结果给出了一组新的聚合输出,比如SQL。