如何在 ElasticSearch 中查询不同的字段值
假设我们有一个名为 strings 的 ElasticSearch 索引,其中包含 {"type": "keyword"} 类型的 pattern 字段。
获取列的前 N 个值
如果我们想获取前 N 个(在我们的示例中为 12)条目,即出现在最多文档中的 pattern,我们可以使用此查询:
terms_aggregation_query.json
{
"aggs" : {
"patterns" : {
"terms" : {
"field" : "pattern.keyword",
"size": 12
}
}
}
}Python 完整示例:
es_terms_example.py
from elasticsearch import Elasticsearch
es = Elasticsearch()
result = es.search(index="strings", body={
"aggs" : {
"patterns" : {
"terms" : {
"field" : "pattern.keyword",
"size": 12
}
}
}
})
for aggregation in result["aggregations"]["patterns"]["buckets"]:
print(aggregation) # e.g. {'key': 'mypattern, 'doc_count': 2802}请参见 terms 聚合文档了解更多信息。
获取列的所有不同值
获取所有值稍微复杂一些,因为我们需要使用返回 after_key 来分页查询的复合聚合。
此 Python 辅助函数将使用可配置的页面大小自动分页查询:
es_iterate_distinct.py
from elasticsearch import Elasticsearch
es = Elasticsearch()
def iterate_distinct_field(es, fieldname, pagesize=250, **kwargs):
"""
辅助函数:从 ElasticSearch 获取所有不同的值
(按出现次数排序)
"""
compositeQuery = {
"size": pagesize,
"sources": [{
fieldname: {
"terms": {
"field": fieldname
}
}
}
]
}
# 迭代页面
while True:
result = es.search(**kwargs, body={
"aggs": {
"values": {
"composite": compositeQuery
}
}
})
# 生成每个桶
for aggregation in result["aggregations"]["values"]["buckets"]:
yield aggregation
# 设置 "after" 字段
if "after_key" in result["aggregations"]["values"]:
compositeQuery["after"] = \
result["aggregations"]["values"]["after_key"]
else: # 完成!
break
# 用法示例
for result in iterate_distinct_field(es, fieldname="pattern.keyword", index="strings"):
print(result) # 例如 {'key': {'pattern': 'mypattern'}, 'doc_count': 315}Check out similar posts by category:
Databases, ElasticSearch, Python
If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow