Lucene 4分页

hud*_*onb 6 java lucene pagination

我正在使用Lucene 4.2并且正在实现结果分页.

IndexSearcher.searchAfter提供了一种实现"下一页"功能的有效方法,但实现"上一页"甚至"转到页面"功能的最佳方法是什么?没有IndexSearcher.searchBefore例子.

我正在考虑确定给定页面大小的页面总数,并保持一个ScoreDoc[]数组来跟踪ScoreDoc每个页面的"后" (该数组将在结果被分页时填充).这将允许我使用"最近" ScoreDoc的使用IndexSearcher.searchAfter(或空在最坏的情况下).

这有意义吗?有更好的方法吗?

Jai*_*ide 13

我一直在使用Lucene 4.8并且一直在开发包含分页的REST接口.我的解决方案是使用TopScoreDocCollector并调用topDocs(int startIndex,int numberOfhits)方法.通过将基于零的页码乘以命中数来计算起始索引.

...
DirectoryReader reader = DirectoryReader.open(MMapDirectory.open( java.io.File(indexFile) );
IndexSearcher searcher = new IndexSearcher(reader);
TopScoreDocCollector collector = TopScoreDocCollector.create(MAX_RESULTS, true);  // MAX_RESULTS is just an int limiting the total number of hits 
int startIndex = (page -1) * hitsPerPage;  // our page is 1 based - so we need to convert to zero based
Query query = new QueryParser(Version.LUCENE_48, "All", analyzer).parse(searchQuery);
searcher.search(query, collector);
TopDocs hits = collector.topDocs(startIndex, hitsPerPage);
...
Run Code Online (Sandbox Code Playgroud)

所以我的REST接口接受页码和每页点击次数作为参数.因此,前进或后退就像提交具有适当页面值的新请求一样简单


Ral*_*lph 5

我同意Jaimie解释的解决方案.但我想指出你必须要注意的另一个方面,那就是帮助理解搜索引擎的一般机制.

使用TopDocCollector,您可以在按结果或其他排序标准对结果进行排序之前,定义您希望与搜索查询匹配的匹配数.

请参阅以下示例:

collector = TopScoreDocCollector.create(9999, true);
searcher.search(parser.parse("Clone Warrior"), collector);
// get first page
topDocs = collector.topDocs(0, 10);
int resultSize=topDocs.scoreDocs.length; // 10 or less
int totalHits=topDocs.totalHits; // 9999 or less
Run Code Online (Sandbox Code Playgroud)

我们告诉Lucene这里最多收集9999个包含搜索短语"Clone Warrior"的文档.这意味着,如果索引包含超过9999个包含此搜索短语的文档,收集器将在填充9999次点击后停止!

这意味着,您选择MAX_RESULTS越大越好,成为您的搜索结果.但是,只有当你期望大量的点击时,这才有意义.另一方面,如果你搜索"luke skywalker"并且你只期望一次命中,那么MAX_RESULTS也可以设置为1.

因此,更改MAX_RESULTS会影响返回的scoreDocs,因为将对收集的匹配执行排序.实际上,将MAX_RESULTS设置为足够大的尺寸,以便人类用户不能争辩错过特定文档.这个概念完全违背SQL数据库的行为,SQL数据库总是考虑完整的数据池.

但lucene也支持另一种机制.您可以,而不是为收集器定义MAX_RESULTS,或者定义您希望等待结果集的时间量.因此,例如,您可以定义始终要在300ms后停止收集器.这是保护应用程序性能问题的好方法.但是,如果您想确保计算所有相关文档而不是将MAX_RESULTS参数或最大等待时间设置为无穷大值.