Lucene è piuttosto un grande argomento con un sacco di classi e metodi per coprire, e che normalmente non può utilizzare senza comprensione a almeno alcuni concetti di base. Se hai bisogno di un servizio rapidamente disponibile, usa invece Solr. Se hai bisogno del pieno controllo di Lucene, continua a leggere. Tratterò alcuni concetti e classi chiave di Lucene, che li rappresentano. (Per informazioni su come leggere i file di testo nella memoria, ad esempio, articolo this).
Qualsiasi cosa tu voglia fare in Lucene - indicizzazione o ricerca - hai bisogno di un analizzatore. L'obiettivo dell'analizzatore è di tokenizzare (irrompere nelle parole) e arginare (ottenere una base di una parola) il testo di input. Inoltre getta le parole più frequenti come "a", "il", ecc. È possibile trovare gli analizzatori per più di 20 lingue, oppure è possibile utilizzare SnowballAnalyzer e passare la lingua come parametro.
Per creare un'istanza di SnowballAnalyzer per l'inglese questo:
Analyzer analyzer = new SnowballAnalyzer(Version.LUCENE_30, "English");
Se avete intenzione di testi di indice in diverse lingue, e desidera selezionare automaticamente analizzatore, è possibile utilizzare tika's LanguageIdentifier.
È necessario memorizzare l'indice da qualche parte. Ci sono 2 possibilità principali per questo: indice in memoria, che è facile da provare, e indice del disco, che è il più diffuso.
Utilizzare uno dei prossimi 2 linee:
Directory directory = new RAMDirectory(); // RAM index storage
Directory directory = FSDirectory.open(new File("/path/to/index")); // disk index storage
Quando si desidera aggiungere, aggiornare o cancellare i documenti, è necessario IndexWriter:
IndexWriter writer = new IndexWriter(directory, analyzer, true, new IndexWriter.MaxFieldLength(25000));
Qualsiasi documento (file di testo nel tuo caso) è un set di campi. Per creare il documento, che conterrà informazioni sul file, utilizzare questo:
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
costruttore prende il nome di campo, è il testo e almeno 2 più parametri. La prima è una bandiera, che mostra se Lucene deve conservare questo campo. Se è uguale a Field.Store.YES
, avrai la possibilità di recuperare tutto il tuo testo dall'indice, altrimenti verranno memorizzate solo le informazioni dell'indice su di esso.
Secondo parametro indica se Lucene deve indicizzare questo campo oppure no. Utilizzare Field.Index.ANALYZED
per qualsiasi campo su cui si sta effettuando la ricerca.
Normalmente, si usano entrambi i parametri come mostrato sopra.
Non dimenticare di chiudere il IndexWriter
dopo il lavoro è fatto:
writer.close();
ricerca è un po 'complicato. Avrete bisogno di diverse classi: Query
e QueryParser
per fare domanda Lucene dalla stringa, IndexSearcher
per la ricerca vera e propria, TopScoreDocCollector
per memorizzare i risultati (si passa alla IndexSearcher
come parametro) e ScoreDoc
per scorrere i risultati. Successivo frammento di codice mostra come tutto questo è composto da:
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 secondo argomento al costruttore QueryParser
- è campo di default, vale a dire di campo che verrà cercato se non di qualificazione è stato dato. Ad esempio, se la tua query è "title: term", Lucene cercherà una parola "term" nel campo "title" di tutti i documenti, ma se la tua query è solo "term" se cercherà nel campo predefinito, in questo caso - "contenuti". Per maggiori informazioni vedi Lucene Query Syntax.
QueryParser
prende anche l'analizzatore come ultimo argomento. Questo deve essere lo stesso analizzatore usato per indicizzare il testo.
L'ultima cosa che devi sapere è un primo parametro TopScoreDocCollector.create
. È solo un numero che rappresenta il numero di risultati che desideri raccogliere. Ad esempio, se è uguale a 100, Lucene raccoglierà solo i primi (per punteggio) 100 risultati e lascerà cadere il resto. Questo è solo un atto di ottimizzazione: raccogli i risultati migliori e, se non sei soddisfatto, ripeti la ricerca con un numero maggiore.
Infine, non dimenticare di chiudere ricercatore e la directory di risorse di sistema non sciolti:
searcher.close();
directory.close();
EDIT: vedere anche IndexFiles demo class da Lucene 3.0 sources.
ho provato questo http://pastebin.com/HqrbBPtp, ma senza successo ... – celsowm
Nella riga 80 hai: 'QueryParser parser = new QueryParser (Version.LUCENE_30," computer ", analizzatore);', cioè si imposta il secondo parametro (campo predefinito) su "computer", quindi si esegue una ricerca senza qualificatore. Lucene cerca di usare _field_ "computer" predefinito per trovare _term_ "computer", e poiché il tuo documento non ha questo campo, Lucene fallisce. Utilizzare 'parser QueryParser = new QueryParser (Version.LUCENE_30," content ", analyzer);' oppure cercare con qualificatore: 'Query query = parser.parse (" content: computer ");'. – ffriend