【问题标题】:How to paginate terms aggregation results in Elasticsearch如何在 Elasticsearch 中对术语聚合结果进行分页
【发布时间】:2021-01-01 10:00:53
【问题描述】:

我一直在尝试找出一种方法来对 Elasticsearch 中的术语聚合结果进行分页,但到目前为止我还没有达到预期的结果。

这是我要解决的问题。在我的索引中,我有一堆文档,它们的分数(与 ES _score 分开)是根据文档中其他字段的值计算的。每个文档“属于”一个客户,由 customer_id 字段引用。文档还有一个id,由doc_id字段引用,与ES元字段_id相同。这是一个例子。

{
 '_id': '1',
 'doc_id': '1',
 'doc_score': '85',
 'customer_id': '123'
}

对于每个 customer_id,有多个文档,所有文档都有不同的文档 ID 和不同的分数。我想要做的是,给定一个客户 ID 列表,返回每个 customer_id 的顶部文档(每个客户只有 1 个)并且能够对类似于 的结果进行分页常规 ES 搜索 API 中的 sizefrom 方法。我要用于文档分数的字段是 doc_score 字段。

到目前为止,在我当前的 Python 脚本中,我尝试的是一个带有“top hits”聚合的嵌套 aggs,只为每个客户获取顶部文档。

{
 "size": 0,
 "query:": {
  "bool": {
   "must": [
    {
     "match_all": {}
    },
    {
     "terms": {
      "customer_id": customer_ids # a list of the customer ids I want documents for
     }
    },
    {
     "exists": {
      "field": "score" # sometimes it's possible a document does not have a score
     }
    }
   ]
  }
 }
 "aggs": {
  "customers": {
   "terms" : {
    {"field": "customer_id", "min_doc_count": 1},
    "aggs": {
     "top_documents": {
      "top_hits": {
       "sort": [
        {"score": {"order": "desc"}}
       ],
       "size": 1
      }
     }
    }
   }
  }
 }
}

然后,我通过遍历每个客户存储桶来“分页”,将顶部文档 blob 附加到列表中,然后根据 score 字段的值对列表进行排序,最后获取切片 @987654323 @。

问题在于,假设列表中有 500 个客户,但我只想要第二个 20 个文档,即size = 20from=20。因此,每次调用该函数时,我都必须先获取 500 个客户中每个客户的列表,然后再进行切片。这听起来效率很低,而且也是一个速度问题,因为我需要尽可能快地实现该功能。

理想情况下,我可以直接从 ES 获取第二个 20,而无需在我的函数中进行任何切片。

我研究了 ES 提供的 Composite 聚合,但在我看来我无法在我的情况下使用它,因为我需要获取整个文档,即 _source 中的所有内容 常规搜索 API 响应中的字段。

如果有任何建议,我将不胜感激。

【问题讨论】:

    标签: python elasticsearch


    【解决方案1】:

    最好的方法是使用分区

    根据文档:

    GET /_search
    {
       "size": 0,
       "aggs": {
          "expired_sessions": {
             "terms": {
                "field": "account_id",
                "include": {
                   "partition": 1,
                   "num_partitions": 25
                },
                "size": 20,
                "order": {
                   "last_access": "asc"
                }
             },
             "aggs": {
                "last_access": {
                   "max": {
                      "field": "access_date"
                   }
                }
             }
          }
       }
    }
    

    https://www.elastic.co/guide/en/elasticsearch/reference/6.8/search-aggregations-bucket-terms-aggregation.html#_filtering_values_with_partitions

    【讨论】:

    • 原来你的回答并没有完全解决我的问题,但我能够重新解决问题并利用你提供的解决方案,所以谢谢你!
    • 感谢您的反馈。由于这是一个反复出现的问题,我写了一篇文章来帮助其他人对聚合结果进行分页spoon-elastic.com/all-elastic-search-post/…
    猜你喜欢
    • 2019-07-12
    • 1970-01-01
    • 2021-09-22
    • 2020-10-26
    • 2014-07-09
    • 1970-01-01
    • 2020-02-26
    • 2021-06-06
    • 1970-01-01
    相关资源
    最近更新 更多