我有一些索引在Elasticsearch上的文档,看起来像这些样本:
{'country': 'France', 'collected': '2015-03-12', 'value': 20}
{'country': 'Canada', 'collected': '2015-03-12', 'value': 21}
{'country': 'Brazil', 'collected': '2015-03-12', 'value': 33}
{'country': 'France', 'collected': '2015-02-01', 'value': 10}
{'country': 'Canada', 'collected': '2015-02-01', 'value': 11}
{'country': 'Mexico', 'collected': '2015-02-01', 'value': 9}
...
我想构建一个查询,每个国家/地区获得一个结果,只获得max(collected)
的结果。
因此,对于上面显示的示例,结果将类似于:
{'country': 'France', 'collected': '2015-03-12', 'value': 20}
{'country': 'Canada', 'collected': '2015-03-12', 'value': 21}
{'country': 'Brazil', 'collected': '2015-03-12', 'value': 33}
{'country': 'Mexico', 'collected': '2015-02-01', 'value': 9}
我意识到我需要在country
上进行汇总,但我无法理解如何限制max(collected)
上的结果。
有什么想法吗?
答案 0 :(得分:45)
您可以使用country
字段上的top_hits
聚合,每组返回1个文档,并按收集的日期降序对文档进行排序:
POST /test/_search?search_type=count
{
"aggs": {
"group": {
"terms": {
"field": "country"
},
"aggs": {
"group_docs": {
"top_hits": {
"size": 1,
"sort": [
{
"collected": {
"order": "desc"
}
}
]
}
}
}
}
}
}
答案 1 :(得分:1)
对于那些遇到“默认情况下在文本字段中禁用了字段数据的user1892775”的人,您可以创建一个多字段(https://www.elastic.co/guide/en/elasticsearch/reference/current/multi-fields.html)。所以你可能有这样的映射:
"mapping": {
"properties": {
"country": {"type": "string", "fields": {"raw": {"type": "string", "index": "not_analyzed"}}}
}
然后您的查询看起来像
POST /test/_search?search_type=count
{
"aggs": {
"group": {
"terms": {
"field": "country.raw"
},
"aggs": {
"group_docs": {
"top_hits": {
"size": 1,
"sort": [
{
"collected": {
"order": "desc"
}
}
]
}
}
}
}
}
}
(注意使用country。 raw )
答案 2 :(得分:0)
标记为正确的答案对我来说非常有用。 这是我添加一些额外过滤器的方法。这是 AWS 上的 7.4 版。
我分组依据的字段是一个名为 tags 的关键字字段。
对于每个组(标签),获取按 date_uploaded 降序排列的前 3 个文档。
同时显示每组(标签)内的文档总数。
仅考虑属于用户 22 的未删除文档。
只返回 10 个组(标签),按字母顺序排序。
对于每个文档,返回其 ID (book_id) 和 date_uploaded。 (默认为返回所有信息。)
Size:0 可防止查询返回有关所有文档的大量信息。
{'query': {'bool': {'filter': [{'terms': {'user_id': [22]}}, {'terms': {'deleted': ['false']}}]}},
'size': 0,
"aggs": {
"group": {
"terms": {
"field": "tags.keyword",
"size":10,
"order":{ "_key": "asc" }
},
"aggs": {
"group_docs": {
"top_hits": {
"size": 3,
"_source":["book_id","date_uploaded"],
"sort": [ {"date_uploaded": { "order": "desc" }}]
}
}
}
}
}
}
这里是如何获取每个组(在我的例子中是标签)和每个组的文档匹配。
query_results = ... result of query
buckets = query_results["aggregations"]["group"]["buckets"]
for bucket in buckets:
tag = bucket["key"]
tag_doc_count = bucket["doc_count"]
print tag, tag_total_doc_count
tag_hits = bucket["group_docs"]["hits"]["hits"]
for hit in tag_hits:
source = hit["_source"]
print source["book_id"], source["date_uploaded"]
仅供参考,“组”术语可以命名为任何名称。从查询结果中获取存储桶时,请确保使用相同的名称。