2009-06-08 11 views
19

Preguntándose cómo lograr la paginación en Lucene, ya que no es inherentemente compatible con la paginación. Básicamente, necesito buscar 'top 10 entries' (basado en algún parámetro), luego 'next 10 entries', etc. Y al mismo tiempo, no quiero que Lucene acapare la memoria. Cualquier consejo sería apreciado. Gracias de antemano.cómo lograr la paginación en lucene?

+0

verificación de la respuesta aprobada en este post: [4 Lucene paginación] [1] [1]: http://stackoverflow.com/a/24533377/1080485 –

Respuesta

20

Tendrá que aplicar su propio mecanismo de búsqueda, algo similar a la siguiente.

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

Usted encontrará que la iteración de la matriz scoreDocs será ligera como los datos contenidos en el índice no se utiliza realmente hasta que se llama al método searcher.Doc.

Tenga en cuenta que este ejemplo fue escrito en contra de una versión ligeramente modificada del Lucene.NET 2.3.2, pero el principio básico debe trabajar contra cualquier versión reciente de Lucene.

+1

Estoy de acuerdo , los resultados en Lucene no son tan pesados ​​como los resultados al consultar una base de datos para que pueda implementar fácilmente métodos de paginación personalizados sin tener que lidiar con problemas de rendimiento –

+1

El problema aquí es cuando busca un gran conjunto de datos con mayor número de paginación. . Es como buscar algo y luego omitir una parte de la búsqueda. – Ruwantha

11

Otra versión del ciclo, continuando con el fragmento de código de 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

Uso la siguiente forma de paginar, puede ser que ayude a alguien. Si conoce una mejor estrategia, específicamente desde el punto de vista del rendimiento, comparta.

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