您需要申请nested aggregations。既然你来自python,就跟着python脚本走吧:
from elasticsearch import Elasticsearch
# Connect to the elastic cluster
es=Elasticsearch([{'host':'localhost','port':9200}])
your_data = [
{ "name": "name1","age": 20 },
{ "name": "name2","age": 23 },
{ "name": "name3","age": 20 },
{ "name": "name1","age": 22 },
{ "name": "name4","age": 18 },
{ "name": "name2","age": 23 },
{ "name": "name4","age": 18 },
{ "name": "name4","age": 14 }
]
your_index_name = "test_index"
# indexing your exemple data
for doc in your_data:
es.index(index=your_index_name, body=doc)
首先,您需要为每个名称创建文档存储桶,我称之为“buckets_for_name”,然后在 buckets_for_name 内部应用年龄的嵌套术语聚合:
# the nested aggregation query
query = {
"aggs": {
"buckets_for_name": {
"terms": { "field": "name.keyword" },
"aggs": {
"age_terms": {
"terms": {
"field": "age"
}
}
}
}
}
}
res = es.search(index=your_index_name, body=query)
# the results are here
res["aggregations"]["buckets_for_name"]["buckets"]
结果并不如你所愿:
[{'key': 'name4',
'doc_count': 3,
'age_terms': {'doc_count_error_upper_bound': 0,
'sum_other_doc_count': 0,
'buckets': [{'key': 18, 'doc_count': 2}, {'key': 14, 'doc_count': 1}]}},
{'key': 'name1',
'doc_count': 2,
'age_terms': {'doc_count_error_upper_bound': 0,
'sum_other_doc_count': 0,
'buckets': [{'key': 20, 'doc_count': 1}, {'key': 22, 'doc_count': 1}]}},
{'key': 'name2',
'doc_count': 2,
'age_terms': {'doc_count_error_upper_bound': 0,
'sum_other_doc_count': 0,
'buckets': [{'key': 23, 'doc_count': 2}]}},
{'key': 'name3',
'doc_count': 1,
'age_terms': {'doc_count_error_upper_bound': 0,
'sum_other_doc_count': 0,
'buckets': [{'key': 20, 'doc_count': 1}]}}]
所以清洁它。这里有一个建议:
pretty_results = []
for result in res["aggregations"]["buckets_for_name"]["buckets"]:
d = dict()
d["name"] = result["key"]
d["ages"] = []
for age in result["age_terms"]["buckets"]:
d["ages"].append(age["key"])
pretty_results.append(d)
漂亮的输出:
[{'name': 'name4', 'ages': [18, 14]},
{'name': 'name1', 'ages': [20, 22]},
{'name': 'name2', 'ages': [23]},
{'name': 'name3', 'ages': [20]}]