Eine kurze Einführung in die Indizierung/Suche mit Lucene
Manchmal benötige ich ein Indizierungstool, das so etwas wie eine eingebettete Datenbank darstellt. Dies ist ein eingebetteter Index. Dies kommt…
Manchmal benötige ich ein Indizierungstool, das so etwas wie eine eingebettete Datenbank darstellt. Dies ist ein eingebetteter Index. Dies kommt vor, wenn ich versuche, Filter über Daten in einer großen visuellen Tabelle oder über eine andere Visualisierung laufen zu lassen.
Vom Standpunkt der Kodierung aus betrachtet, könnte der erste Versuch der Filterung etwa so aussehen:
public List<String> filter(String userFilterText) {
List<String> ret = new LinkedList<String>();
for( Entity e : entities ) {
if( e.containsText(userFilterString) {
ret.add(e.getEntityId());
}
}
return ret;
}
Irgendwann übersteigt die Anzahl der Zeilen oder Datenelemente die Fähigkeit, zeitnah auf die Benutzeranfrage zu reagieren. Selbst wenn Sie versuchen, die Daten zu sammeln und in einer Speicherstruktur abzulegen, wird dies irgendwann nicht mehr möglich sein.
Die Lösung besteht darin, einen Index zu erstellen, der in die Anwendung eingebettet ist und die Filterung verwaltet. Das bedeutet, dass das Filtern zu einer Aufgabe wird:
public List<String> filter(String userFilterText) {
List<String> ret = index.query(userFilterText);
return ret;
}
Obwohl dies bei einer kleinen Anzahl von Objekten etwas langsamer ist, ist es nie wirklich so langsam, dass es die Benutzerperspektive beeinträchtigt. Das heißt, wenn es sehr viel Material gibt, wird man erwarten, dass es etwas langsamer geht, und das ist akzeptabel. Außerdem bietet der Filter jetzt die Möglichkeit, nach Feldern zu filtern, anstatt nur etwas wie String.contains() oder sogar reguläre Ausdrücke zu verwenden.
Das Erstellen eines dieser Indizes ist ganz einfach. Sie fügen Daten mit Document.add(Field) hinzu. Sie fragen mit searcher.search(Query, Collector) ab. Es ist wirklich so einfach. Für weniger als 1000 Zeilen Code können Sie ein recht nützliches Modul erhalten.
Die Klasse IndexProvider.java ist das Herzstück des Beispiels. Sie rufen IndexProvider.index(data) für jedes Objekt auf, das Sie indizieren müssen. Und dann können Sie IndexProvider.search(String) aufrufen, um den aufgebauten Index zu durchsuchen.
Der Einstiegspunkt ist Example.main() und hat eine künstliche Anforderung. Wenn das Beispiel zum ersten Mal ausgeführt wird, erstellt es ein Verzeichnis namens index und indexiert example.csv. Bei der zweiten Ausführung wird eine Abfrage nach ‚the‘ über den Inhalt ausgeführt.
Andere, kompliziertere Abfragen sind möglich. Um den gesamten Lorem-Text zu erhalten
ut eu
Um ein bestimmtes Feld zu erhalten,
+ut +f1:two
Dadurch kann die Filterung der Visualisierung genauso umfangreich sein wie jede Abfrage. Und, was noch wichtiger ist, die Filterung kann an beliebige Daten gebunden werden, ohne dass der Code geändert werden muss.
Klicken Sie hier ->lucene-starter, um eine .tgz-Datei mit einem pom und den Quellen herunterzuladen.