2009-06-08 82 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; 
    }