Wie erhalte ich eine Liste aller Token aus dem Lucene 8.6.1-Index?

Nov 20 2020

Ich habe mir angesehen, wie man eine Liste aller Token aus dem Solr / Lucene-Index erhält. aber Lucene 8.6.1 scheint nicht zu bieten IndexReader.terms(). Wurde es verschoben oder ersetzt? Gibt es einen einfacheren Weg als diese Antwort ?

Antworten

2 andrewjames Nov 20 2020 at 09:03

Einige Geschichten

Sie haben gefragt: Ich frage mich nur, ob Sie IndexReader.terms()umgezogen sind oder durch eine Alternative ersetzt wurden.

Die Lucene v3-Methode IndexReader.terms()wurde AtomicReaderin Lucene v4 verschoben . Dies wurde in den Versionshinweisen zu v4 alpha dokumentiert .

(Denken Sie daran, dass Lucene v4 bereits 2012 veröffentlicht wurde.)

Die Methode in AtomicReaderVersion 4 hat einen Feldnamen .

In den Versionshinweisen zu Version 4 heißt es:

Ein großer Unterschied besteht darin, dass Feld und Begriffe jetzt getrennt aufgelistet werden: Ein TermsEnum liefert ein BytesRef (umschließt ein Byte []) pro Begriff in einem einzelnen Feld, nicht in einem Begriff.

Der Schlüsselteil dort ist "pro Begriff innerhalb eines einzelnen Feldes" . Ab diesem Zeitpunkt gab es keinen einzigen API-Aufruf mehr, um alle Begriffe aus einem Index abzurufen.

Dieser Ansatz hat zu späteren Versionen durchgesetzt - außer , dass die AtomicReaderund AtomicReaderContextKlassen umbenannt wurden LeafReaderund LeafReaderContextin Lucene v 5.0.0. Siehe Lucene-5569 .

Aktuelle Veröffentlichungen

Dadurch haben wir die Möglichkeit, auf Begriffslisten zuzugreifen - allerdings nur auf Feldbasis:

Der folgende Code basiert auf der neuesten Version von Lucene (8.7.0), sollte jedoch auch für die von Ihnen erwähnte Version (8.6.1) gelten - am Beispiel mit Java:

private void getTokensForField(IndexReader reader, String fieldName) throws IOException {
    List<LeafReaderContext> list = reader.leaves();

    for (LeafReaderContext lrc : list) {
        Terms terms = lrc.reader().terms(fieldName);
        if (terms != null) {
            TermsEnum termsEnum = terms.iterator();

            BytesRef term;
            while ((term = termsEnum.next()) != null) {
                System.out.println(term.utf8ToString());
            }
        }
    }
}

Im obigen Beispiel wird ein Index wie folgt angenommen:

private static final String INDEX_PATH = "/path/to/index/directory";
...
IndexReader reader = DirectoryReader.open(FSDirectory.open(Paths.get(INDEX_PATH)));

Wenn Sie Feldnamen aufzählen müssen, kann der Code in dieser Frage einen Ausgangspunkt bieten.

Schlussbemerkung

Ich denke , man kann auch den Zugriff Begriffe auf einer pro Dokument Basis anstelle einer pro Feld Basis, wie sie in den Kommentaren erwähnt. Ich habe das nicht versucht.