ElasticSearch 中 MongoDB .distinct(...) 的等效方法

假设我们有一个名为 strings 的 ElasticSearch 索引,其中包含 {"type": "keyword"} 类型的 pattern 字段。

现在我们想要执行 MongoDB db.getCollection('...').distinct('pattern') 的等效操作:

解决方案

在 Python 中你可以使用此之前关于 ElasticSearch distinct 的文章中的 iterate_distinct_field() 辅助函数。完整示例:

elasticsearch_distinct_helper.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