如何使用偏移+限制> 1000的ES查询

Posted

技术标签:

【中文标题】如何使用偏移+限制> 1000的ES查询【英文标题】:How to use ES query with offset+limit >1000 【发布时间】:2021-04-02 07:17:00 【问题描述】:

我为我的客户端公开了一个 API,我使用 ES 来获取特定时间范围内的数据。这个数字是记录远远超过 100 万。现在,我必须提供另一个功能,我为它们提供偏移量和限制,客户端可以从偏移量中获取记录数(限制)。

我的 ES 查询是这样形成的

"from":10000,"size":2001,"timeout":"60s","query":"bool":"must":["terms":"tollId":["59850"],"boost":1.0,"range":"updatedAt":"from":"2020-08-15T00:00:00.000Z","to":null,"include_lower":true,"include_upper":true,"boost":1.0,"range":"updatedAt":"from":null,"to":"2020-12-15T22:08:21.000Z","include_lower":true,"include_upper":true,"boost":1.0],"adjust_pure_negative":true,"boost":1.0,"sort":["updatedAt":"order":"desc"]

当我在 Elastic Search 上执行此操作时,我得到

"failed_shards": [

  "shard": 0,
  "index": "companydatabase",
  "node": "vQU6NjSVRK6dKNLsWkfqEw",
  "reason": 
  "type": "query_phase_execution_exception",
  "reason": "Result window is too large, from + size must be less than or equal to: [10000] but was [12001]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level setting."

解决方案是使用 Scroll API 来获取记录,但是当我必须从某个偏移量到某个限制获取记录时,我不能使用滚动 API。

我错过了什么吗?有什么办法可以解决这个问题,否则我每次都必须获取所有记录(文档)并过滤结果?

【问题讨论】:

【参考方案1】:

您只需将索引设置max_result_window 更新为更高的值,默认为10000。因此,例如,如果您的 from + size 小于 10000 它会正常工作,您需要为该索引更改 max_result_window

curl -XPUT "http://localhost:4200/the_index/_settings" -d ' "index" :  "max_result_window" : 500000  ' -H "Content-Type: application/json"

显然,为 ES 使用滚动 API 将使这个更有效的替代方案。

【讨论】:

@Dharman 这是一种解决方案。但正如我告诉你的那样,记录的数量超过 100 万条。它不会影响我的 API 的性能吗? 它需要更多的堆和内存 + 时间,具体取决于 from + size 总和所以简而言之是的。您应该使用滚动 API,但如果您的服务器有足够的内存,短期内就可以了。要么不要让客户端达到 9999 并请求超过 10000 的任何报告,要么更改您的逻辑以使用滚动 API。 谢谢。我有点知道 Scroll API 将是我最后的手段,但最终带来如此多的记录并根据偏移量和限制过滤它们将再次对我的堆产生影响。

以上是关于如何使用偏移+限制> 1000的ES查询的主要内容,如果未能解决你的问题,请参考以下文章

Elasticsearch 字段限制超过 1000

如何在 Oracle 11g 的“选择”查询中添加偏移量?

如何获取超过1000?

如何在 mongodb 中使用偏移量和限制?

ES文档级查询匹配限制

如何加快 LIMIT 子句中偏移量较大的 MySQL 查询?