如何在Lucene的数百万条记录中实现适当的分页

时间:2017-03-10 11:09:47

标签: java pagination lucene

我的Lucene索引中有超过1000万个文档,我需要在我的应用程序中实现PROPER分页。每份文件都是大学候选人的独特记录。目前,我每页显示5条记录,并在用户的前端提供分页。

一旦执行搜索,页面编号1就会显示5条记录。现在有一些按钮可以将用户带到第一页,下一页,上一页和最后一页。

现在例如我的搜索查询总命中数为1000万,当我点击最后一页时,我基本上会转到页码2000000(200万)。在后端,我在lucene搜索函数中传递pageNumber * 5作为maxSearch(int)。这需要花费大量时间来获取结果。

请参阅截图,查看前端Screenshot

的结果

这就是我在后端做的事情,

Backend Code Backend Code 2

我的命中从未计算过。这个过程在搜索时陷入困境。请建议我实施正确解决方案的解决方案。

P.S。我正在使用Lucene 4.0.0。

1 个答案:

答案 0 :(得分:1)

有几种方法可能有所帮助:

将所有分页留给Lucene

您可以避免hits.ScoreDocs上的手动循环迭代,如Lucene 4 Pagination问题中的接受答案中所述。

光标

如果基于Lucene的分页方法的表现不够,您可以尝试实现游标:

任何(找到的)文档都有排序位置,例如元组(sort field value, docId)。第二个元组元素消除了相同的排序值问题。

因此,您可以将排序位置传递到下一页和上一页,并使用排序过滤器而不是迭代。

例如:

在第一页中,我们看到三个文档(按日期排序): (date: 2017-01-01, docId: 10)(date: 2017-02-02, docId: 3)(date: 2017-02-02, docId: 5)

第二页将从(date >= 2017-02-02 OR (date == 2017-02-02 AND docId > 5)的第一个(按排序)文档开始。

此外,可以在搜索过程中为多个页面缓存此位置。

关于改变指数的分页问题

分页通常适用于特定索引版本(如果在用户交互中间更新索引,结果分页可能会提供不良体验 - 文档位置可能因添加和删除行或修改现有文档的排序字段值而有所不同。)< / p>

有时我们必须“在搜索时”提供搜索结果,显示索引的“快照”,但对于大型索引来说这是非常棘手的。

存储在客户端的游标(通常是不透明的字符串)在索引更新时会严重破坏分页。

通常,有一些查询可以提供非常大的结果,并且后端可以使用WeakMapcoreCacheKey进行此查询来缓存页面游标。

特殊的最后一页处理

当且仅当“最后一页”是频繁操作时,您可以按相反的顺序对结果进行排序,并获得最后一页文档,与反向结果相反。

在实施相反的订单时,请注意相同的价值问题。