Elasticsearch 2.1:“结果”窗口太大(index.max_result_window)


86

我们从Elasticsearch 2.1检索信息,并允许用户翻阅结果。当用户请求较高的页码时,我们会收到以下错误消息:

结果窗口太大,从+大小必须小于或等于:[10000],但为[10020]。请参阅滚动API,以获取请求大型数据集的更有效方法。可以通过更改[index.max_result_window]索引级别参数来设置此限制

弹性文档表示,这是因为内存消耗高,并且要使用滚动api:

大于的值会在每次搜索和执行搜索的每个分片上消耗大量的堆内存。保留此值是最安全的,因为它是任何深度滚动使用滚动API的https://www.elastic.co/guide/zh-cn/elasticsearch/reference/2.x/breaking_21_search_changes.html#_from_size_limits

问题是我不想检索大型数据集。我只想从数据集中检索一个切片,该切片在结果集中很高。滚动文档也说:

滚动不适用于实时用户请求https://www.elastic.co/guide/en/elasticsearch/reference/2.2/search-request-scroll.html

这给我一些问题:

1)如果我使用滚动api向上滚动到结果10020(而不考虑低于10000的所有内容),而不是对结果10000-10020进行“正常”搜索请求,则内存消耗是否会真正降低(如果有,为什么)?

2)滚动API似乎不是我的选择,但我必须增加“ index.max_result_window”。有人对这个有经验么?

3)还有其他选择可以解决我的问题吗?

Answers:


79

如果需要深度分页,一种可能的解决方案是增加该值max_result_window。您可以curl从shell命令行使用以下方法:

curl -XPUT "http://localhost:9200/my_index/_settings" -H 'Content-Type: application/json' -d '{ "index" : { "max_result_window" : 500000 } }'

我没有注意到内存使用量增加了,值约为100k。


我有同样的错误'Result window is too large, from + size must be less than or equal to: [10000] but was [47190]. 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 parameter.')它说有4719页(每10页显示结果)。而且我认为您的建议有效。
dotlash

1
对于少于500000的少量文档来说,这是一个很好的解决方案
Ezzat

2
我使用的是ES v2.2.0,因此必须更改有效负载{ "max_result_window" : 500000 }才能正常工作。因此,curl命令变成了-curl -XPUT "http://localhost:9200/my_index/_settings" -d '{ "max_result_window" : 500000 }'
帕林Porecha

3
对于使用此命令获取较新版本的Elasticsearch头错误的用户,还需要传递头,curl -XPUT“ localhost:9200 / my_index / _settings ” -H“内容类型:application / json” -d'{ “ index”:{“ max_result_window”:50000}}'
表示

32

正确的解决方案是使用滚动。
但是,如果要将结果search返回值扩展到10,000个以上,则可以使用Kibana轻松实现:

转到Dev Tools并将以下内容发布到您的索引(your_index_name),并指定新的“最大结果”窗口

在此处输入图片说明

PUT your_index_name/_settings
{ 
  "max_result_window" : 500000 
}

如果一切顺利,您应该看到以下成功响应:

{
  "acknowledged": true
}

1
我尝试在Elasticsearch代码(put_settings等)中遵循此方法,但遇到许多错误。这节省了我几个小时!谢谢!
cpres

24

弹性文档中的以下页面谈论深度分页:

https://www.elastic.co/guide/zh-CN/elasticsearch/guide/current/pagination.html https://www.elastic.co/guide/en/elasticsearch/guide/current/_fetch_phase.html

根据文档的大小,分片的数量以及所使用的硬件,完全可以分页10,000至50,000个结果(1,000至5,000页)。但是,有了足够多的值,使用大量的CPU,内存和带宽,排序过程的确会变得非常繁重。因此,我们强烈建议您不要进行深度分页。


1
所以在这里,我们应该放弃深度分页,对吗?基本上,对于单个查看者而言,分页4000页没有任何意义。可以说,谷歌搜索,我们几乎没有滚动到第8或9页来检查结果。通常,我们只处理Google提供给我们的前3-5页。
dotlash

2
如果需要深度分页,是否可以使用滚动API?
Abhi.G

3
但是,当我们启用排序功能时,可以在电子商务网站上说。当用户想查看价格最高的商品时。当我们按最高价格排序时的结果与我们按最低页面排序但转到最后一页时的结果会有所不同吗?由于我们限制了可以访问的结果数。有什么解决办法吗?
Murazza MR 17年

3

使用Scroll API可获得10000多个结果。

ElasticSearch NEST API中的滚动示例

我这样使用它:

private static Customer[] GetCustomers(IElasticClient elasticClient)
{
    var customers = new List<Customer>();
    var searchResult = elasticClient.Search<Customer>(s => s.Index(IndexAlias.ForCustomers())
                          .Size(10000).SearchType(SearchType.Scan).Scroll("1m"));

    do
    {
        var result = searchResult;
        searchResult = elasticClient.Scroll<Customer>("1m", result.ScrollId);
        customers.AddRange(searchResult.Documents);
    } while (searchResult.IsValid && searchResult.Documents.Any());

    return customers.ToArray();
}

0

如果要获得10000个以上的结果,则在所有数据节点中,内存使用量将非常高,因为它必须在每个查询请求中返回更多结果。然后,如果您有更多的数据和更多的分片,则合并这些结果将效率很低。还可以缓存过滤器上下文,因此又有更多的内存。您必须反复试验到底要服用多少。如果在一个小窗口中收到许多请求,则应该对多个查询进行超过10k的查询,然后自己将其合并到代码中,这应该占用更少的应用程序内存,然后增加窗口大小。


0

2)滚动API似乎不是我的选择,但我必须增加“ index.max_result_window”。有人对这个有经验么?

->您可以在索引模板中定义此值,因为es模板仅适用于新索引,因此您必须在创建模板后删除旧索引,或者等待将新数据吸收到elasticsearch中。

{“ order”:1,“ template”:“ index_template *”,“ settings”:{“ index.number_of_replicas”:“ 0”,“ index.number_of_shards”:“ 1”,“ index.max_result_window”:2147483647},


0

在我的情况下,看起来好像通过from和size前缀减少查询的结果将消除错误,因为我们不需要所有结果:

GET widgets_development/_search
{
  "from" : 0, 
  "size": 5,
  "query": {
    "bool": {}
  },
  "sort": {
    "col_one": "asc"
  }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.