首页 > 解决方案 > 在具有大量存储桶的 Elastic 中导航术语聚合

问题描述

希望每个人都保持安全!

我正在尝试探索在 elasticsearch 中处理以下用例的正确方法

假设我有大约 700000 个文档,我想根据一个字段(我们称之为 primary_id)存储这些文档。对于多个文档,此主 ID 可以相同(通常最多 2-3 个文档将具有相同的 primary_id)。在所有其他情况下,primary_id 不会在任何其他文档中重复。

因此,平均每 10 个文档我将有 8 个唯一的主 ID,并且 2 个文档中的 1 个主 ID 相同

为了确保唯一性,我尝试使用术语聚合,结果我得到了响应我的搜索请求而不是后续滚动请求的存储桶。谷歌搜索后,我发现滚动查询不支持聚合。

结果,我尝试寻找替代解决方案,并在此链接中尝试了解决方案,https://lukasmestan.com/learn-how-to-use-scroll-elasticsearch-aggregation/

它建议使用多个搜索请求,每个请求都指定要获取的分区号(取决于您将结果划分为多少个分区)。但是即使客户端超时设置很高,我也会收到客户端超时。

理想情况下,我想知道处理此类数据的最佳方法是什么,其中形成存储桶的字段的方差几乎等于文档的数量。SQL 等效项是 select DISTINCT (primary_id) from .....

但是在弹性搜索中,不同的事物只能通过分桶(术语聚合)来处理。

我还在术语聚合下使用热门匹配作为子聚合查询来获取 _source 字段。

任何帮助将不胜感激!

谢谢!

标签: elasticsearchaggregation

解决方案


分页聚合有 3 种方法。

  1. 复合聚合
  2. 分割
  3. 桶排序

您已经尝试过的分区。

复合聚合:可以将多个数据源组合在一个存储桶中,并允许对其进行分页和排序。它只能使用 after_key 进行线性分页,即您不能从第 1 页跳转到第 3 页。您可以获取“n”条记录,然后在 key 之后传递返回并获取下一个“n”条记录。

GET index22/_search
{
 "size": 0,
 "aggs": {
   "ValueCount": {
     "value_count": {
       "field": "id.keyword"
     }
   },
   "pagination": {
     "composite": {
       "size": 2,
       "sources": [
         {
           "TradeRef": {
             "terms": {
               "field": "id.keyword"
             }
           }
         }
       ]
     }
   }
 }
}

桶排序

与所有管道聚合一样,bucket_sort 聚合在所有其他非管道聚合之后执行。这意味着排序仅适用于已从父聚合返回的任何存储桶。例如,如果父聚合是术语并且其大小设置为 10,则 bucket_sort 将仅对这 10 个返回的术语桶进行排序

所以这不适合你的情况

您可以通过更新设置 index.max_result_window 将结果大小增加到大于 10K 的值。设置太大的大小会导致内存不足的问题,因此您需要对其进行测试,看看您的硬件可以支持多少。

更好的选择是使用滚动 api 并在客户端执行不同的


推荐阅读