我需要在ES中使用3个字段进行聚合(group-by)。
我可以在一个查询中做到这一点吗?或者我需要对每一列使用facet + iterate?
谢谢
发布于 2013-01-07 14:04:55
您可以通过以下两种方式完成此操作:
1)在单个facet结果中使用多个字段:
单字段facet示例:
curl -X GET "http://localhost:9200/sales/order/_search?pretty=true" -d '{
"query": {
"query_string": {
"query": "shohi*",
"fields": [
"billing_name"
]
}
},
"facets": {
"facet_result": {
"terms": {
"fields": [
"status"
],
"order": "term",
"size": 15
}
}
}
}'单个facet结果中的多个字段的示例:
curl -X GET "http://localhost:9200/sales/order/_search?pretty=true" -d '{
"query": {
"query_string": {
"query": "shohi*",
"fields": [
"billing_name"
]
}
},
"facets": {
"facet_result": {
"terms": {
"fields": [
"status",
"customer_gender",
"state"
],
"order": "term",
"size": 15
}
}
}
}'2)使用多面结果集:
curl -X GET "http://localhost:9200/sales/order/_search?pretty=true" -d '{
"query": {
"query_string": {
"query": "*",
"fields": [
"increment_id"
]
}
},
"facets": {
"status_facets": {
"terms": {
"fields": [
"status"
],
"size": 50,
"order": "term"
}
},
"gender_facets": {
"terms": {
"fields": [
"customer_gender"
]
}
},
"state_facets": {
"terms": {
"fields": [
"state"
],
,
"order": "term"
}
}
}
}'参考链接:http://www.elasticsearch.org/guide/reference/api/search/facets/terms-facet.html
发布于 2014-01-23 15:31:31
从ElasticSearch 1.0版本开始,新的 API允许使用子聚合按多个字段进行分组。假设您希望按字段field1、field2和field3进行分组
{
"aggs": {
"agg1": {
"terms": {
"field": "field1"
},
"aggs": {
"agg2": {
"terms": {
"field": "field2"
},
"aggs": {
"agg3": {
"terms": {
"field": "field3"
}
}
}
}
}
}
}
}当然,您可以对任意多个字段执行此操作。
更新:
为了完整起见,下面是上面查询的输出。下面还有一段python代码,用于生成聚合查询并将结果扁平化为字典列表。
{
"aggregations": {
"agg1": {
"buckets": [{
"doc_count": <count>,
"key": <value of field1>,
"agg2": {
"buckets": [{
"doc_count": <count>,
"key": <value of field2>,
"agg3": {
"buckets": [{
"doc_count": <count>,
"key": <value of field3>
},
{
"doc_count": <count>,
"key": <value of field3>
}, ...
]
},
{
"doc_count": <count>,
"key": <value of field2>,
"agg3": {
"buckets": [{
"doc_count": <count>,
"key": <value of field3>
},
{
"doc_count": <count>,
"key": <value of field3>
}, ...
]
}, ...
]
},
{
"doc_count": <count>,
"key": <value of field1>,
"agg2": {
"buckets": [{
"doc_count": <count>,
"key": <value of field2>,
"agg3": {
"buckets": [{
"doc_count": <count>,
"key": <value of field3>
},
{
"doc_count": <count>,
"key": <value of field3>
}, ...
]
},
{
"doc_count": <count>,
"key": <value of field2>,
"agg3": {
"buckets": [{
"doc_count": <count>,
"key": <value of field3>
},
{
"doc_count": <count>,
"key": <value of field3>
}, ...
]
}, ...
]
}, ...
]
}
}
}下面的python代码在给定字段列表的情况下执行group-by。如果您指定了include_missing=True,它还包括一些缺少字段的值的组合(多亏了this,如果您使用的是Elasticsearch 2.0版本,则不需要它)
def group_by(es, fields, include_missing):
current_level_terms = {'terms': {'field': fields[0]}}
agg_spec = {fields[0]: current_level_terms}
if include_missing:
current_level_missing = {'missing': {'field': fields[0]}}
agg_spec[fields[0] + '_missing'] = current_level_missing
for field in fields[1:]:
next_level_terms = {'terms': {'field': field}}
current_level_terms['aggs'] = {
field: next_level_terms,
}
if include_missing:
next_level_missing = {'missing': {'field': field}}
current_level_terms['aggs'][field + '_missing'] = next_level_missing
current_level_missing['aggs'] = {
field: next_level_terms,
field + '_missing': next_level_missing,
}
current_level_missing = next_level_missing
current_level_terms = next_level_terms
agg_result = es.search(body={'aggs': agg_spec})['aggregations']
return get_docs_from_agg_result(agg_result, fields, include_missing)
def get_docs_from_agg_result(agg_result, fields, include_missing):
current_field = fields[0]
buckets = agg_result[current_field]['buckets']
if include_missing:
buckets.append(agg_result[(current_field + '_missing')])
if len(fields) == 1:
return [
{
current_field: bucket.get('key'),
'doc_count': bucket['doc_count'],
}
for bucket in buckets if bucket['doc_count'] > 0
]
result = []
for bucket in buckets:
records = get_docs_from_agg_result(bucket, fields[1:], include_missing)
value = bucket.get('key')
for record in records:
record[current_field] = value
result.extend(records)
return resulthttps://stackoverflow.com/questions/14181674
复制相似问题