2009-06-08 39 views
19

Tự hỏi làm thế nào để đạt được phân trang trong Lucene, vì nó vốn không hỗ trợ phân trang. Tôi về cơ bản cần phải tìm kiếm 'top 10 mục' (dựa trên một số tham số) sau đó 'tiếp theo 10 mục' và như vậy. Và cùng lúc đó tôi không muốn Lucene nhớ lại. Bất kỳ lời khuyên nào sẽ được đánh giá cao. Cảm ơn trước.làm thế nào để đạt được phân trang trong lucene?

+0

kiểm tra câu trả lời đã được phê duyệt trong bài viết này: [Lucene 4 Pagination] [1] [1]: http://stackoverflow.com/a/24533377/1080485 –

Trả lời

20

Bạn sẽ cần áp dụng cơ chế phân trang của riêng mình, một cái gì đó tương tự như dưới đây.

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)); 
} 

Bạn sẽ thấy rằng việc lặp lại mảng scoreDocs sẽ nhẹ vì dữ liệu chứa trong chỉ mục không thực sự được sử dụng cho đến khi phương thức tìm kiếm được gọi.

Xin lưu ý rằng ví dụ này được viết dựa trên phiên bản Lucene.NET 2.3.2 được sửa đổi một chút, nhưng hiệu trưởng cơ bản sẽ hoạt động đối với bất kỳ phiên bản Lucene gần đây nào.

+1

Tôi đồng ý , kết quả trong Lucene không nặng như kết quả khi truy vấn cơ sở dữ liệu, do đó bạn có thể dễ dàng triển khai phương pháp phân trang tùy chỉnh mà không phải xử lý vấn đề hiệu suất –

+1

Vấn đề ở đây là khi bạn tìm kiếm tập dữ liệu lớn với tìm kiếm số trang cao hơn . Nó giống như bạn tìm kiếm một thứ rồi bỏ qua một phần của tìm kiếm. – Ruwantha

11

Một phiên bản khác của vòng lặp, tiếp tục với đoạn mã của Kane;

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

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

Tôi sử dụng cách sau để phân trang, có thể giúp ích cho ai đó. Nếu bạn biết một chiến lược tốt hơn, cụ thể là từ quan điểm hiệu suất, vui lòng chia sẻ.

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; 
    } 
Các vấn đề liên quan