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

我们从Elasticsearch 2.1中检索信息,并允许用户查看结果。 当用户请求高页码时,我们得到以下错误信息:

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

弹性文件说,这是因为高内存消耗和使用滚动api:

高于的值可能会消耗大量的每个search和每个分片执行search的堆内存。 这是最安全的离开这个值,因为它是一个使用滚动api的任何深度滚动https://www.elastic.co/guide/en/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执行“正常”search请求,内存消耗是否真的会降低(如果是这样,为什么)?

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

3)还有其他的select来解决我的问题吗?

如果你需要大的深度分页,我认为只有一种解决scheme是增加max_result_window的值

curl -XPUT "http://localhost:9200/my_index/_settings" -d '{ "index" : { "max_result_window" : 500000 } }' 

内存使用量的增加,我没有发现〜100k的值

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

https://www.elastic.co/guide/en/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,内存和带宽,分类过程确实会变得非常重要。 为此,我们强烈build议不要进行深度分页。

正确的解决scheme是使用滚动。
但是,如果要将结果search范围扩展到10000个以上,则可以使用Kibana轻松完成search:

转到Dev Tools ,只是发布以下内容到您的索引(your_index_name),指定什么是新的最大结果窗口

在这里输入图像说明

 PUT your_index_name/_settings { "max_result_window" : 500000 } 

如果一切顺利的话,你应该看到以下的成功回应:

 { "acknowledged": true } 

使用滚动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(); } 

如果你想要10000个以上的结果,那么在所有的数据节点中,内存使用率将非常高,因为它必须在每个查询请求中返回更多的结果。 那么如果你有更多的数据和更多的碎片,合并这些结果将是低效的。 另外escachingfilter上下文,因此再次更多的内存。 你必须尝试和错误你正在采取多less。 如果您在小窗口中收到很多请求,您应该执行多个查询超过10k,并将其自行合并到代码中,如果您增加窗口大小,应该占用更less的应用程序内存。

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

– >你可以在索引模板中定义这个值,es模板只适用于新的索引,所以你必须在创build模板后删除旧的索引,或者等待新的数据在elasticsearch中被摄取。

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

你得到这个错误的主要原因 – 这是因为你正在用错误的方式使用弹性search。 ES是一个search引擎。 获取多个元素或多页数据是无效的。 也许你正在试图用弹性search来操作所有的数据,不仅search相关的结果? 这是不正确的。

所以,你应该使用它进行search。 而且我认为,没有必要得到超过10000个结果项目。 例如,谷歌只返回前1000个结果。