In che modo lucene indicizza i documenti?


95

Ho letto un documento su Lucene; inoltre ho letto il documento a questo link ( http://lucene.sourceforge.net/talks/pisa ).

Non capisco davvero come Lucene indicizzi i documenti e non capisco quali algoritmi Lucene utilizza per l'indicizzazione?

Sul link sopra, si dice che Lucene utilizza questo algoritmo per l'indicizzazione:

  • algoritmo incrementale:
    • mantenere una pila di indici di segmento
    • creare indice per ogni documento in arrivo
    • spingere nuovi indici sullo stack
    • sia b = 10 il fattore di unione; M = 8

for (size = 1; size < M; size *= b) {
    if (there are b indexes with size docs on top of the stack) {
        pop them off the stack;
        merge them into a single index;
        push the merged index onto the stack;
    } else {
        break;
    }
}

In che modo questo algoritmo fornisce un'indicizzazione ottimizzata?

Lucene utilizza l'algoritmo B-tree o qualsiasi altro algoritmo simile per l'indicizzazione, o ha un algoritmo particolare?


La maggior parte delle risposte qui sono corrette sul fatto che prima Lucene crea l' indice invertito, ma ciò non spiega il punto chiave di come l'indice di termine viene successivamente cercato (ed è, credo, ciò che l'OP ha effettivamente chiesto). Quindi di seguito trovi una nuova risposta a questa domanda piuttosto vecchia che si spera fornisca una migliore comprensione.
fnl

1
Ho aggiornato ancora una volta la mia risposta, perché le risposte attuali (compresa la mia!) Non sono davvero soddisfacenti per rispondere alle due domande principali dell'OP (come fa Lucene a fornire un'indicizzazione ottimizzata e da quale particolare algoritmo - un Skip-List, non un B-Tree, BTW). Spero che i miei ultimi aggiornamenti ora rispondano correttamente alla domanda reale!
fnl

Risposte:


54

C'è un articolo abbastanza buono qui: https://web.archive.org/web/20130904073403/http://www.ibm.com/developerworks/library/wa-lucene/

Modifica 12/2014: aggiornato a una versione archiviata a causa dell'eliminazione dell'originale, probabilmente la migliore alternativa più recente è http://lucene.apache.org/core/3_6_2/fileformats.html

C'è una versione ancora più recente su http://lucene.apache.org/core/4_10_2/core/org/apache/lucene/codecs/lucene410/package-summary.html#package_description , ma sembra contenere meno informazioni rispetto a quello più vecchio.

In poche parole, quando lucene indicizza un documento, lo scompone in una serie di termini. Quindi memorizza i termini in un file indice in cui ogni termine è associato ai documenti che lo contengono. Potresti considerarlo un po 'come una tabella hash.

I termini vengono generati utilizzando un analizzatore che pone ogni parola alla sua radice. L'algoritmo di stemming più popolare per la lingua inglese è l'algoritmo di stemming di Porter: http://tartarus.org/~martin/PorterStemmer/

Quando viene emessa una query, viene elaborata tramite lo stesso analizzatore utilizzato per creare l'indice e quindi utilizzato per cercare i termini corrispondenti nell'indice. Ciò fornisce un elenco di documenti che corrispondono alla query.


Grazie per la tua risposta e link. Ma ho sentito che il progetto Lucene ha uno stemmer speciale chiamato "Snowball"? Ne hai sentito parlare?
M.Amrollahi

Questa è una domanda diversa: Vedi lucidimagination.com/search/… Oltre a questo, visto il tuo schema di domande ti suggerisco di leggere il libro 'Lucene in Action': manning.com/hatcher2 (La prima edizione è un po 'datata, ma può essere trovato in una versione albero morto. La seconda edizione può essere acquistata come e-book).
Yuval F

5
Puoi modificare la tua risposta, il primo collegamento che è un collegamento IBM non è stato trovato :)
Adelin

Inoltre, come fanno i campi a inserire l'intera immagine? Se una query si trova su un campo specifico, come ea che punto lucene sa che il termine che punta al documento non si trova in un punto qualsiasi del documento, ma all'interno di un campo richiesto?
Levon Tamrazov

44

In poche parole, Lucene costruisce un indice invertito utilizzando Skip-Lists su disco , quindi carica una mappatura per i termini indicizzati in memoria utilizzando un Finite State Transducer (FST). Si noti, tuttavia, che Lucene non carica (necessariamente) tutti i termini indicizzati nella RAM , come descritto da Michael McCandless, l'autore stesso del sistema di indicizzazione di Lucene. Si noti che utilizzando Skip-Lists, l'indice può essere spostato da un hit all'altro, rendendo possibili cose come set e, in particolare, query di intervallo (molto simile a B-Trees). E la voce di Wikipedia sull'indicizzazione delle liste da saltare spiega anche perché l'implementazione della lista da saltare di Lucene è chiamata multi-livelloSkip-List - essenzialmente, per rendere O(log n)possibili le ricerche (di nuovo, molto simile a B-Trees).

Quindi, una volta che l'indice invertito (termine), che si basa su una struttura di dati Skip-List, è stato creato dai documenti, l'indice viene memorizzato su disco. Lucene quindi carica (come già detto: forse, solo alcuni di) quei termini in un trasduttore a stati finiti , in un'implementazione FST liberamente ispirata da Morfologick .

Michael McCandless (anche) fa un lavoro abbastanza buono e conciso nello spiegare come e perché Lucene usa un FST (minimo aciclico) per indicizzare i termini che Lucene immagazzina nella memoria, essenzialmente come un SortedMap<ByteSequence,SomeOutput>, e dà un'idea di base di come funzionano gli FST (cioè, come l'FST compatta le sequenze di byte [cioè i termini indicizzati] per fare in modo che l'uso della memoria di questa mappatura diventi sub-lineare). E indica il documento che descrive il particolare algoritmo FST utilizzato anche da Lucene.

Per chi è curioso perché Lucene utilizza Skip-liste, mentre la maggior parte dei database usano (B +) - e / o (B) -Alberi, dare un'occhiata alla giusta risposta così riguardo a questa domanda (Skip-Elenca vs. B-alberi). Quella risposta fornisce una spiegazione abbastanza buona e profonda - in sostanza, non tanto rendere gli aggiornamenti simultanei dell'indice "più suscettibili" (perché puoi decidere di non riequilibrare un B-Tree immediatamente, ottenendo così circa le stesse prestazioni simultanee di un Skip-List), ma piuttosto, Skip-Lists ti evita di dover lavorare sull'operazione di bilanciamento (ritardata o meno) (in ultima analisi) richiesto da B-Trees (In effetti, come la risposta mostra / fa riferimento, probabilmente c'è una differenza di prestazioni molto piccola tra B-Trees e [multi-level] Skip-List, se entrambi sono "fatti bene".)


1
Inoltre, stanno usando Skip List invece di B-tree per ridurre il numero di ricerche su disco, poiché la parte di Skip List risiede in memoria e pochissime operazioni di I / O del disco richiedono quando si attraversa l'indice
Anton

24

Sembra che la tua domanda sia più sull'unione degli indici che sull'indicizzazione stessa.

Il processo di indicizzazione è abbastanza semplice se ignori i dettagli di basso livello. Lucene forma quello che viene chiamato "indice invertito" dai documenti. Quindi, se arriva un documento con il testo "Essere o non essere" e id = 1, l'indice invertito sarebbe simile a:

[to] → 1
[be] → 1
[or] → 1
[not] → 1

Fondamentalmente è questo: l'indice dalla parola all'elenco dei documenti contenenti una data parola. Ogni riga di questo indice (parola) è chiamata lista dei messaggi. Questo indice viene quindi mantenuto per l'archiviazione a lungo termine.

In realtà ovviamente le cose sono più complicate:

  • Lucene può saltare alcune parole basate sul particolare Analizzatore fornito;
  • le parole possono essere preelaborate utilizzando l'algoritmo di stemming per ridurre la flessibilità del linguaggio;
  • la lista dei messaggi può contenere non solo gli identificatori dei documenti, ma anche l'offset della parola data all'interno del documento (potenzialmente diverse istanze) e alcune altre informazioni aggiuntive.

Ci sono molte altre complicazioni che non sono così importanti per la comprensione di base.

È importante capire, però, che l'indice di Lucene è solo append . A un certo punto l'applicazione decide di eseguire il commit (pubblicare) tutte le modifiche nell'indice. Lucene termina tutte le operazioni di servizio con index e lo chiude, quindi è disponibile per la ricerca. Dopo il commit dell'indice sostanzialmente immutabile. Questo indice (o parte di indice) è chiamato segmento . Quando Lucene esegue la ricerca di una query, cerca in tutti i segmenti disponibili.

Quindi sorge la domanda: come possiamo modificare il documento già indicizzato ?

Nuovi documenti o nuove versioni di documenti già indicizzati vengono indicizzati in nuovi segmenti e vecchie versioni invalidate in segmenti precedenti utilizzando la cosiddetta kill list . La kill list è l'unica parte dell'indice sottoposto a commit che può cambiare. Come puoi immaginare, l'efficienza dell'indice diminuisce con il tempo, perché i vecchi indici potrebbero contenere per lo più documenti rimossi.

È qui che entra in gioco la fusione. Merging - è il processo di combinazione di diversi indici per rendere l'indice complessivamente più efficiente. Ciò che accade fondamentalmente durante l'unione è che i documenti live vengono copiati nel nuovo segmento e i vecchi segmenti rimossi completamente.

Utilizzando questo semplice processo Lucene è in grado di mantenere l'indice in buona forma in termini di prestazioni di ricerca.

Spero che ti aiuti.


1
Quindi, per trovare prima i risultati più aggiornati, una ricerca inizierebbe esaminando i segmenti più recenti? Quindi, solo per chiarire, supponiamo che un documento venga aggiornato. La versione precedente del documento viene aggiunta alla kill list, quindi qualsiasi corrispondenza che si trova nei segmenti più vecchi viene rimossa dai risultati della ricerca se il loro ID documento corrisponde a un id nella kill list?
Joel B

2
Sì hai ragione. L'unica cosa da menzionare è che l'ordine finale è definito utilizzando regole di ordinamento (indice di rilevanza in casi banali), quindi l'ordine in cui i segmenti vengono cercati non è rilevante.
Denis Bazhenov

12

È indice invertito , ma ciò non specifica quale struttura utilizza. Il formato dell'indice in lucene ha informazioni complete.
Inizia con "Riepilogo delle estensioni di file".

Noterai innanzitutto che parla di vari indici diversi. Per quanto ho potuto notare nessuno di questi usa in senso stretto un albero B , ma ci sono somiglianze: le strutture sopra assomigliano agli alberi.


1
L'indice invertito di Lucene si basa su un elenco di salto, non su un albero B. Ancora una struttura ad albero in un senso molto ampio, ma solo per essere completo - ad esempio, vedi questa domanda SO re. L'uso di Lucene di una skip list e questa domanda quindi perché skip-list potrebbe essere preferibile rispetto B-alberi .
fnl
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.