2010-11-03 26 views

Respuesta

33

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.

+0

He intentado esto http://pastebin.com/HqrbBPtp, pero sin éxito ... – celsowm

+0

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

3
package org.test; 

import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileReader; 
import java.io.IOException; 


import org.apache.lucene.queryParser.*; 
import org.apache.lucene.search.IndexSearcher; 
import org.apache.lucene.search.Query; 
import org.apache.lucene.search.ScoreDoc; 
import org.apache.lucene.search.TopScoreDocCollector; 
import org.apache.lucene.store.Directory; 
import org.apache.lucene.store.FSDirectory; 
import org.apache.lucene.store.LockObtainFailedException; 
import org.apache.lucene.analysis.standard.StandardAnalyzer; 
import org.apache.lucene.index.CorruptIndexException; 
import org.apache.lucene.index.IndexWriter; 
import org.apache.lucene.store.RAMDirectory; 
import org.apache.lucene.util.Version; 
import org.apache.lucene.document.Document; 
import org.apache.lucene.document.Field; 

public class LuceneSimple { 

private static void addDoc(IndexWriter w, String value) throws IOException { 
    Document doc = new Document(); 
    doc.add(new Field("title", value, Field.Store.YES, Field.Index.ANALYZED)); 
    w.addDocument(doc); 
} 



public static void main(String[] args) throws CorruptIndexException, LockObtainFailedException, IOException, ParseException { 

    File dir = new File("F:/tmp/dir"); 

    StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_30); 

    Directory index = new RAMDirectory(); 
    //Directory index = FSDirectory.open(new File("lucDirHello")); 


    IndexWriter w = new IndexWriter(index, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED); 

    w.setRAMBufferSizeMB(200); 

    System.out.println(index.getClass() + " RamBuff:" + w.getRAMBufferSizeMB()); 

    addDoc(w, "Lucene in Action"); 
    addDoc(w, "Lucene for Dummies"); 
    addDoc(w, "Managing Gigabytes"); 
    addDoc(w, "The Art of Computer Science"); 
    addDoc(w, "Computer Science ! what is that ?"); 


    Long N = 0l; 

    for(File f : dir.listFiles()){ 
     BufferedReader br = new BufferedReader(new FileReader(f)); 
     String line = null; 
     while((line = br.readLine()) != null){ 
     if(line.length() < 140) continue;  
     addDoc(w, line); 
     ++N; 
     } 
     br.close(); 
    } 

    w.close(); 

    // 2. query 
    String querystr = "Computer"; 

    Query q = new QueryParser(Version.LUCENE_30, "title", analyzer).parse(querystr); 


    //search 
    int hitsPerPage = 10; 

    IndexSearcher searcher = new IndexSearcher(index, true); 

    TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true); 

    searcher.search(q, collector); 

    ScoreDoc[] hits = collector.topDocs().scoreDocs; 

    System.out.println("Found " + hits.length + " hits."); 
    for(int i=0;i<hits.length;++i) { 
     int docId = hits[i].doc; 
     Document d = searcher.doc(docId); 
     System.out.println((i + 1) + ". " + d.get("title")); 
    } 


    searcher.close(); 

} 

} 
+0

puede establecer la variable "Archivo dir" en el directorio que necesita para indexar. – smartnut007

Cuestiones relacionadas