如何在源数据频繁更改时处理分页

时间:2015-01-15 17:11:06

标签: elasticsearch pagination paging

具体来说,我正在使用Elasticsearch进行分页,但这个问题可能适用于任何数据库。

Elasticsearch为paginate search results提供方便的fromto参数。

所以我运行了一个查询get me the most recent data from result 1 to 10

这很有效。

用户点击“下一页”,查询为: get me the most recent data from result 11 to 20

问题是,在两个查询之间的时间内,后备数据库中添加了2个新记录,这意味着分页结果将重叠(第一页的最后2个显示为第二页上的前两个) )。

避免这种情况的最佳解决方案是什么?现在,我在查询中添加了一个过滤器,告诉它只包含比上一个查询的最后结果晚的结果。但它似乎只是hackish。

3 个答案:

答案 0 :(得分:8)

如果您已经为相关时间戳编制索引,则过滤器不是一个糟糕的选择。您必须在客户端跟踪该时间戳才能正确准备查询。你还必须知道何时摆脱它。但这些并非难以克服的问题。

Scroll API是一个可靠的选项,因为它可以在Elasticsearch方面及时快速创建快照。 Scroll API的目的是为深度分页提供稳定的搜索查询,该查询必须处理您遇到的确切更改问题。

您通过提供查询和scroll参数开始Scrolling Search,Elasticsearch为其返回scroll_id。然后,您向提供该ID的/_search/scroll发出请求,每个ID都返回一个结果页面,并为下一个请求返回新的scroll_id

(请注意,您想要scan搜索类型。这用于提取文档 en masse,并且不应用任何排序。 )

与过滤相比,您仍然需要跟踪一个值:scroll_id用于下一页结果。这是否比跟踪时间戳更容易取决于您的应用。

还有其他潜在的缺点需要考虑。 Elasticsearch会在群集中的单个节点上保留搜索的上下文。可以想象,这些可能会累积在您的群集中,具体取决于您依赖滚动搜索的程度。您需要测试那里的性能影响。如果我没记错的话,滚动搜索也不会因节点故障或重启而持续存在。

Scroll API的ES文档提供了有关上述所有内容的详细信息。

底线:按时间戳过滤实际上并不是一个糟糕的选择。 Scroll API是另一个有效的选项,专为类似的用例而设计,但并非没有缺点。

答案 1 :(得分:2)

意识到这有点旧了,但是在ElasticSearch 6.3中,请求正文现在有了search_after功能,它允许进行游标类型的分页:

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-search-after.html

  

它与滚动API非常相似,但与之不同的是,search_after参数是无状态的,始终会针对最新版本的搜索器进行解析。

答案 2 :(得分:-1)

您需要使用扫描API。扫描和滚动API让您进行时间点搜索和分页。 扫描API -