2009-06-08 103 views
19

想知道如何在Lucene中實現分頁,因爲它本身不支持分頁。我基本上需要搜索「前10個條目」(基於某個參數),然後搜索「下10個條目」等等。同時,我不希望Lucene佔用內存。 任何建議,將不勝感激。 在此先感謝。如何在lucene中實現分頁?

+0

檢查在這個崗位覈定回答: [Lucene的4分頁] [1] [1]:http://stackoverflow.com/a/24533377/1080485 – 2015-09-07 12:10:35

回答

20

您將需要應用您自己的分頁機制,類似於下面的內容。

IList<Document> luceneDocuments = new List<Document>(); 

IndexReader indexReader = new IndexReader(directory); 
Searcher searcher = new IndexSearcher(indexReader); 

TopDocs results = searcher.Search("Your Query", null, skipRecords + takeRecords); 
ScoreDoc[] scoreDocs = results.scoreDocs; 

for (int i = skipRecords; i < results.totalHits; i++) 
{ 
     if (i > (skipRecords + takeRecords) - 1) 
     { 
      break; 
     } 

     luceneDocuments.Add(searcher.Doc(scoreDocs[i].doc)); 
} 

你會發現,在遍歷數組scoreDocs將是輕量級的是不是真的使用包含在索引中的數據,直到searcher.Doc方法被調用。

請注意,這個例子是針對Lucene.NET 2.3.2稍微修改過的版本編寫的,但基本的主體應該可以針對任何最新版本的Lucene。

+1

我同意,在查詢數據庫時,Lucene的結果並不像結果那樣沉重,因此您可以輕鬆實現自定義分頁方法,而無需處理性能問題 – 2009-06-08 07:59:10

11

循環的另一個版本,繼續凱恩的代碼片段;

.................... 

ScoreDoc[] scoreDocs = results.scoreDocs; 
int pageIndex = [User Value]; 
int pageSize = [Configured Value]; 

int startIndex = (pageIndex - 1) * pageSize; 
int endIndex = pageIndex * pageSize; 
endIndex = results.totalHits < endIndex? results.totalHits:endIndex; 

for (int i = startIndex ; i < endIndex ; i++) 
{ 
    luceneDocuments.Add(searcher.Doc(scoreDocs[i].doc)); 
} 
2

我用下面的方式來分頁,可能會幫助別人。如果你知道更好的策略,特別是從性能的角度來看,請分享。

public TopDocs search(String query, int pageNumber) throws IOException, ParseException { 
     Query searchQuery = parser.parse(query); 
     TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true); 

     int startIndex = (pageNumber - 1) * MyApp.SEARCH_RESULT_PAGE_SIZE; 
     searcher.search(searchQuery, collector); 

     TopDocs topDocs = collector.topDocs(startIndex, MyApp.SEARCH_RESULT_PAGE_SIZE); 
     return topDocs; 
    }