Elasticsearch分页的最佳方法是什么?

7
什么是使用Elasticsearch进行分页的最佳方法?目前,我正在开发一个使用Python后端和Elasticsearch的API,我的索引没有太多数据,因此我们默认在前端使用JavaScript进行分页(到目前为止,我们没有任何问题)。我想知道对于更大的索引,处理分页的最佳方法是什么:
- 滚动API - 切片滚动 - search_after

1
请在此处查看:https://dev59.com/x6nka4cB1Zd3GeqPU9s4 - Lupanoide
你有多少个文档?它少于10k吗? - Nikolay Vasiliev
@NikolayVasiliev,我的索引有大约5万个,但我正在考虑使用更大的索引。 - Andrex
在这种情况下,Lupanoide发布的链接应该会有所帮助。 - Nikolay Vasiliev
2个回答

17
Elasticsearch默认的分页方式是使用from/size参数。然而,这种方式只适用于前1万个搜索结果。
如果需要超过1万个结果,则应使用search_after
如果需要转储整个索引,并且它包含超过1万个文档,则使用scroll API
所有这些查询都允许检索部分搜索结果,但它们有重大区别。
from/size是最便宜和最快的,这就是谷歌在使用Elasticsearch时会用来获取第二、第三等搜索结果页面的方法。
滚动API很昂贵,因为它创建了一个索引的快照,确保在滚动结束时,您将获得与开始时相同的数据。执行滚动请求将消耗资源,同时并行运行多个请求可能会影响性能,因此请谨慎处理。
相反,Search after则介于两者之间:

search_after不是自由跳转到随机页面的解决方案,而是可以并行滚动多个查询。它与scroll API非常相似,但与之不同的是,search_after参数是无状态的,它总是针对搜索器的最新版本进行解析。因此,在遍历过程中,排序顺序可能会根据索引的更新和删除而发生变化。

因此,它将允许您在成本为一些可能的不一致性的情况下分页超过10k。

为什么有10k限制?

index.max_result_window设置为10k作为硬限制,以避免内存不足的情况:

index.max_result_window

用于搜索此索引的from + size的最大值。默认为10000. 搜索请求需要与from + size成比例的堆内存和时间,这会限制该内存。

切片滚动怎么样?

Sliced scroll只是普通滚动的更快速的方法:它允许并行下载文档集合。切片只是滚动查询输出中的文档子集。


-2
    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
    end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接