2013-03-23 78 views
5

我正在使用Lucene 4.2並正在執行結果分頁。Lucene 4分頁

IndexSearcher.searchAfter提供了一種實現「下一頁」功能的有效方式,但實現「上一頁」或甚至「上頁」功能的最佳方式是什麼?例如沒有IndexSearcher.searchBefore

我正在考慮確定給定頁面大小的頁面總數,並保持ScoreDoc[]陣列跟蹤每個頁面的「之後」ScoreDoc(該數組將填充爲頁面結果)。這將允許我使用「最接近的」ScoreDoc用於IndexSearcher.searchAfter(或在最壞情況下爲零)。

這是否有意義?有更好的方法嗎?

+0

嗨,你能解釋一下在lucene 4.x和我也面臨同樣的問題的分頁。 – 2014-02-04 12:23:49

+0

我一直在使用上面第三段討論的方法。除了非常深的分頁(沒有意外),它表現相當好。 – hudsonb 2014-02-11 11:38:07

回答

11

我一直在使用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); 
... 

因此,我的REST接口接受每個頁面的頁碼和點擊次數作爲參數。 所以前進或後退就像提交一個新的請求一樣簡單,頁面的適當值

+0

謝謝Jaimie,我喜歡這種方法。 – hudsonb 2014-07-02 14:54:50

4

我同意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 

我們告訴Lucene的這裏收藏最多包含搜索短語「克隆戰士」 9999個文件。這意味着,如果索引包含超過9999個包含該搜索短語的文檔,收集器將在填充9999個匹配後停止!

這意味着,您選擇MAX_RESULTS的次數越多,您的搜索結果越好。但是這隻有在你期望有大量的點擊時纔有意義。 另一方面,如果您搜索「luke skywalker」並且您只會期待一次命中,那麼MAX_RESULTS也可以設置爲1.

因此,更改MAX_RESULTS會影響返回的scoreDocs,因爲將執行排序在收集的點擊。實際上,將MAX_RESULTS設置爲足夠大的大小,以便人類用戶不會錯過錯過特定文檔。這個概念完全違背了SQL數據庫的行爲,它始終考慮完整的數據池。

但lucene也支持另一種機制。您可以代替爲收集器定義MAX_RESULTS,而是定義要等待結果集的時間量。例如,你可以定義你總是想在300ms後停止收集器。這是一個很好的方法來保護您的應用程序的性能問題。但是,如果您想確保計算所有相關文檔,則必須將MAX_RESULTS的參數或最大等待時間設置爲無限值。