Lucene es una bastante grande tema con una gran cantidad de clases y métodos para cubrir, y normalmente no se puede utilizar sin conocimiento en al menos algunos conceptos básicos. Si necesita un servicio rápidamente disponible, use Solr en su lugar. Si necesitas un control total de Lucene, sigue leyendo. Cubriré algunos conceptos y clases centrales de Lucene, que los representan. (Para obtener información sobre cómo leer archivos de texto en la lectura de memoria, por ejemplo, artículo this).
Lo que sea que vaya a hacer en Lucene - indización o búsqueda - necesita un analizador. El objetivo del analizador es el de tokenizar (dividir en palabras) y derivar (obtener la base de una palabra) su texto de entrada. También arroja las palabras más frecuentes como "a", "the", etc. Puede encontrar analizadores para más de 20 idiomas, o puede usar SnowballAnalyzer y pasar el idioma como parámetro.
Para crear instancia de SnowballAnalyzer de Inglés esto:
Analyzer analyzer = new SnowballAnalyzer(Version.LUCENE_30, "English");
Si va a textos de índice en diferentes idiomas, y desea seleccionar analizador de forma automática, puede utilizar tika's LanguageIdentifier.
Necesita almacenar su índice en algún lugar. Hay dos posibilidades principales para esto: el índice en memoria, que es fácil de probar, y el índice del disco, que es el más extendido.
utilizar cualquiera de los siguientes 2 líneas:
Directory directory = new RAMDirectory(); // RAM index storage
Directory directory = FSDirectory.open(new File("/path/to/index")); // disk index storage
Cuando se desea añadir, actualizar o borrar documento, es necesario IndexWriter:
IndexWriter writer = new IndexWriter(directory, analyzer, true, new IndexWriter.MaxFieldLength(25000));
Cualquier documento (archivo de texto en su caso) es una conjunto de campos. Para crear el documento, que contendrá información sobre el archivo, utilice esto:
Document doc = new Document();
String title = nameOfYourFile;
doc.add(new Field("title", title, Field.Store.YES, Field.Index.ANALYZED)); // adding title field
String content = contentsOfYourFile;
doc.add(new Field("content", content, Field.Store.YES, Field.Index.ANALYZED)); // adding content field
writer.addDocument(doc); // writing new document to the index
Field
constructor toma el nombre de campo, que es el texto y al menos 2 más parámetros. Primero es una bandera, que muestra si Lucene debe almacenar este campo. Si es igual a Field.Store.YES
, tendrá la posibilidad de recuperar todo el texto del índice; de lo contrario, solo se almacenará la información del índice.
El segundo parámetro muestra si Lucene debe indexar este campo o no. Use Field.Index.ANALYZED
para cualquier campo en el que vaya a buscar.
Normalmente, utiliza ambos parámetros como se muestra arriba.
No se olvide de cerrar su IndexWriter
después de que el trabajo está hecho:
writer.close();
La búsqueda es un poco complicado. Necesitará varias clases: Query
y QueryParser
para hacer consulta de Lucene de la cadena, IndexSearcher
para la búsqueda real, TopScoreDocCollector
para almacenar los resultados (se pasa a IndexSearcher
como parámetro) y ScoreDoc
iterar a través de resultados. Siguiente fragmento de código muestra cómo todo esto está compuesto por:
IndexSearcher searcher = new IndexSearcher(directory);
QueryParser parser = new QueryParser(Version.LUCENE_30, "content", analyzer);
Query query = parser.parse("terms to search");
TopScoreDocCollector collector = TopScoreDocCollector.create(HOW_MANY_RESULTS_TO_COLLECT, true);
searcher.search(query, collector);
ScoreDoc[] hits = collector.topDocs().scoreDocs;
// `i` is just a number of document in Lucene. Note, that this number may change after document deletion
for (int i = 0; i < hits.length; i++) {
Document hitDoc = searcher.doc(hits[i].doc); // getting actual document
System.out.println("Title: " + hitDoc.get("title"));
System.out.println("Content: " + hitDoc.get("content"));
System.out.println();
}
Nota segundo argumento del constructor QueryParser
- es campo por defecto, es decir, el campo que será buscado aunque no se especifique calificador. Por ejemplo, si su consulta es "título: término", Lucene buscará una palabra "término" en el campo "título" de todos los documentos, pero si su consulta es solo "término" si buscará en el campo predeterminado, en este caso - "contenido". Para más información, vea Lucene Query Syntax.
QueryParser
también toma el analizador como último argumento. Debe ser el mismo analizador que usaste para indexar tu texto.
Lo último que debe saber es un primer parámetro TopScoreDocCollector.create
. Es solo un número que representa la cantidad de resultados que desea recolectar. Por ejemplo, si es igual a 100, Lucene solo obtendrá los primeros 100 resultados (por puntuación) y descartará el resto. Esto es solo un acto de optimización: usted obtiene los mejores resultados y, si no está satisfecho con ello, repite la búsqueda con un número mayor.
Por último, no se olvide de cerrar buscador y directorio para los recursos del sistema, no sueltas:
searcher.close();
directory.close();
EDIT: Véase también IndexFiles demo class de Lucene 3.0 sources.
He intentado esto http://pastebin.com/HqrbBPtp, pero sin éxito ... – celsowm
En la línea 80 tiene: 'QueryParser parser = new QueryParser (Version.LUCENE_30," computadora ", analizador);', es decir configura el segundo parámetro (campo predeterminado) en "computadora", y luego busca sin calificador. Lucene intenta usar _field_ "computadora" predeterminada para encontrar _term_ "computadora", y como su documento no tiene dicho campo, Lucene falla. Use 'QueryParser parser = new QueryParser (Version.LUCENE_30," content ", analyzer);' o busque con qualifier: 'Query query = parser.parse (" content: computer ");'. – ffriend