2011-03-25 10 views
6

Estoy buscando realizar una consulta con el fin de mantener la integridad interna; por ejemplo, eliminando todos los rastros de un campo/valor particular del índice. Por lo tanto, es importante que encuentre todos los documentos coincidentes (no solo los documentos n superiores), pero el orden en que se devuelven es irrelevante.¿Cuál es la forma más eficiente de recuperar todos los documentos coincidentes de una consulta en Lucene, sin clasificar?

De acuerdo con los documentos, parece que necesito usar el método Searcher.Search(Query, Collector), pero no hay una clase de recopiladores integrada que haga lo que necesito.

¿Debo obtener mi propio recopilador para este propósito? ¿Qué debo tener en cuenta al hacer eso?

+0

tener esto en cuenta si desea devolver todos los resultados: http: //forums.alfresco.com/en/viewtopic.php?t=13381 –

+0

@Rodrigo ¿Podría ser un poco más específico? Leí ese hilo, pero parece tener que ver con las verificaciones de permisos. ¿Puedes explicarme cómo es relevante para mi pregunta? – devios1

Respuesta

4

Resulta que esto fue mucho más fácil de lo que esperaba. Acabo de utilizar la implementación de ejemplo en http://lucene.apache.org/java/2_9_0/api/core/org/apache/lucene/search/Collector.html y grabé los números de documento pasados ​​al método Collect() en una lista, exponiéndolo como una propiedad pública Docs.

que luego simplemente iterar esta propiedad, pasando el número de vuelta a la Searcher para conseguir el correcto Document:

var searcher = new IndexSearcher(reader); 
var collector = new IntegralCollector(); // my custom Collector 
searcher.Search(query, collector); 
var result = new Document[ collector.Docs.Count ]; 
for (int i = 0; i < collector.Docs.Count; i++) 
    result[ i ] = searcher.Doc(collector.Docs[ i ]); 
searcher.Close(); // this is probably not needed 
reader.Close(); 

Hasta ahora parece estar funcionando bien en las pruebas preliminares.

Actualización: Aquí está el código para IntegralCollector:

internal class IntegralCollector: Lucene.Net.Search.Collector { 
    private int _docBase; 

    private List<int> _docs = new List<int>(); 
    public List<int> Docs { 
     get { return _docs; } 
    } 

    public override bool AcceptsDocsOutOfOrder() { 
     return true; 
    } 

    public override void Collect(int doc) { 
     _docs.Add(_docBase + doc); 
    } 

    public override void SetNextReader(Lucene.Net.Index.IndexReader reader, int docBase) { 
     _docBase = docBase; 
    } 

    public override void SetScorer(Lucene.Net.Search.Scorer scorer) { 
    } 
} 
+1

Simplemente recuerde utilizar el valor de docBase pasado a su 'SetNextReader', ya que la identificación del documento pasada a' Collect' es específica para el lector actual (de 'SetNextReader'). Tendrá que usar (docBase + doc) cuando calcule los ids para usar con el lector superior, el usado al abrir su 'IndexSearcher'. – sisve

+0

Además, no olvide 'IndexWriter.DeleteDocuments (Query)' si desea eliminar documentos coincidentes. – sisve

+0

@Simon - Gracias, me di cuenta de eso, cuando comencé a obtener resultados flojos. Además, la eliminación fue solo un ejemplo, de hecho necesito recuperar los documentos en mi aplicación real. – devios1

0

No es necesario escribir un colector de éxito si sólo está mirando para conseguir todos los objetos del documento en el índice. Sólo bucle de 0 a maxDoc() y llamar reader.document() en cada ID de documento, asegurándose de omitir los documentos que ya están eliminados:

for (int i=0; i<reader.maxDoc(); i++) { 
    if (reader.isDeleted(i)) 
     continue; 
    results[i] = reader.document(i); 
} 
+0

Gracias, pero estoy interesado en realizar una consulta, no solo en obtener todos los documentos en el índice. – devios1

Cuestiones relacionadas