根据经验,使用ES进行分页的最佳方式是什么?目前,我正在开发一个在后台使用Elastic (通过python)的应用程序接口,而我的索引没有太多数据,所以默认情况下,我们在JavaScript (前端)中进行分页,没有任何问题。我想知道对于更大的索引,使用Scroll API、切片或search_after进行分页的最佳方式是什么。
发布于 2019-12-03 00:20:26
在Elasticsearch中对搜索结果进行分页的默认方式是使用from/size参数。然而,这只适用于排名前10k的搜索结果。
以防你需要超越这一点,方法就是search_after。
如果需要转储整个索引,并且它包含的文档超过10k,可以使用scroll API。
有什么关系呢?
所有这些查询都允许检索部分搜索结果,但它们有很大的区别。
from/size是最便宜和最快的,如果Google使用Elasticsearch,它会用来搜索第二,第三等搜索结果页面。
滚动API的开销很大,因为在您创建第一个查询时,它会创建一种索引快照,以确保在滚动结束时,您将拥有与索引开始时存在的数据完全相同的数据。执行滚动请求将消耗资源,并且并行运行许多滚动请求可能会降低您的性能,因此请谨慎操作。
Search after是介于两者之间的一种方式:
search_after不是一种可以自由跳转到任意页面的解决方案,而是可以并行滚动多个查询的解决方案。它与搜索器API非常相似,但与之不同的是,search_after参数是无状态的,它总是针对最新版本的scroll进行解析。因此,在遍历过程中,排序顺序可能会根据索引的更新和删除而改变。
因此,它将允许您分页超过10k,代价是一些可能的不一致。
为什么是10k的限制?
为避免out of memory situations,index.max_result_window设置为10k作为硬限制
index.max_result_window
对此索引进行搜索时from + size的最大值。默认为10000。搜索请求占用堆内存和时间与from + size成正比,这限制了内存。
那切片卷轴呢?
Sliced scroll只是一种更快的普通滚动方式:它允许并行下载文档集合。Slice只是滚动查询输出中文档的一个子集。
发布于 2020-10-19 15:26:51
response_array = []
response = ElkConfigClient.search index: "index_name",
body: {
query: {
bool: {
must: [
"search_query"
]
}
}
},
scroll: '1h',
size: 1000
scroll_id = response["_scroll_id"]
s_id = scroll_id
#iterate the response
response["hits"]["hits"].each do |response|
response_array.push(response)
end
while (true)
next_response = ElkConfigClient.scroll(scroll_id: s_id, scroll: '1h')
next_scroll_id = next_response["_scroll_id"]
s_id = next_scroll_id
break if next_response["hits"]["hits"].length == 0
next_response["hits"]["hits"].each do |response|
response_array.push(response)
end
response_array
endhttps://stackoverflow.com/questions/59105657
复制相似问题