Apache Lucene
Denkt man heutzutage an eine Suchmaschine, haben alle zunächst Google im Kopf. Auch Betreiber von Websites nutzen Google in Form der Custom Search Engine (CSE), um Nutzern schnell und einfach eine Suchfunktion für ihre eigenen Inhalte anzubieten. Doch selbstverständlich ist das nicht die einzige – und für viele Website-Betreiber auch nicht die beste – Möglichkeit, den Besuchern eine Volltextsuche anzubieten. Stattdessen können Sie Lucene verwenden: ein kostenloses Open-Source-Projekt von Apache.
Zahlreiche Firmen haben Apache Lucene bei sich eingebunden – entweder online oder offline. Die Wikipedia hatte bis vor einigen Jahren Lucene als Suchfunktion implementiert und nutzt inzwischen Solr, das auf Lucene aufbaut, und auch die Suche bei Twitter läuft komplett über Lucene. Aus dem Projekt, das von Doug Cutting Ende der 1990er als Hobby gestartet wurde, hat sich inzwischen eine Software entwickelt, von der täglich Millionen von Menschen profitieren.
Zahlreiche Firmen haben Apache Lucene bei sich eingebunden – entweder online oder offline. Die Wikipedia hatte bis vor einigen Jahren Lucene als Suchfunktion implementiert und nutzt inzwischen Solr, das auf Lucene aufbaut, und auch die Suche bei Twitter läuft komplett über Lucene. Aus dem Projekt, das von Doug Cutting Ende der 1990er als Hobby gestartet wurde, hat sich inzwischen eine Software entwickelt, von der täglich Millionen von Menschen profitieren.
Was ist Lucene?
Bei Lucene handelt es sich um eine Programmbibliothek, die von der Apache Software Foundation veröffentlicht wird. Sie ist Open Source und für jeden kostenlos zu benutzen und zu verändern. Ursprünglich hat man Lucene komplett in Java geschrieben, inzwischen gibt es aber auch Portierungen in andere Programmiersprachen. Mit Apache Solr und Elasticsearch gibt es mächtige Erweiterungen, die der Suchfunktion noch mehr Möglichkeiten geben.
Lucene ist eine Volltextsuche. Das bedeutet ganz simpel gesprochen: Ein Programm durchsucht eine Reihe von Textdokumenten nach einem oder mehreren vom Nutzer bestimmten Begriffen. Darin erkennt man schon, dass Lucene gar nicht ausschließlich im Kontext des World Wide Webs Verwendung findet – auch wenn die Suchfunktionen hier omnipräsent sind. Auch für Archive, Bibliotheken oder sogar den heimischen Desktop-PC kann man Lucene einsetzen. Lucene durchsucht nämlich nicht nur HTML-Dokumente, sondern arbeitet z. B. auch mit E-Mail oder sogar PDF-Dateien.
Ausschlaggebend für die Suche ist ein Index – das Herz von Lucene: Hier sind alle Begriffe aller Dokumente gespeichert. Ein solcher Inverted Index ist prinzipiell nur eine Tabelle – zu jedem Begriff ist die entsprechende Position gespeichert. Damit man einen Index aufbauen kann, bedarf es zunächst einer Extrahierung. Alle Begriffe müssen aus allen Dokumenten gezogen und im Index gespeichert werden. Lucene gibt Nutzern die Möglichkeit, diese Extrahierung individuell zu konfigurieren. Entwickler entscheiden sich bei der Konfiguration, welche Felder sie in den Index aufnehmen möchten. Um dies zu verstehen, muss man einen Schritt zurückgehen.
Die Objekte, mit denen Lucene arbeitet, sind Dokumente in jeglicher Form. Die Dokumente selbst enthalten aber – aus der Sichtweise von Lucene gesprochen – Felder. In diesen stehen z. B. der Name der Autorin, der Titel des Dokuments oder der Dateiname des selbigen. Jedes Feld hat eine eindeutige Bezeichnung und einen Wert. So kann das Feld mit der Bezeichnung title etwa den Wert „Gebrauchsanweisung für Apache Lucene“ haben. Beim Erstellen des Indexes kann man sich also entscheiden, welche Metadaten man aufnehmen möchte.
Bei der Indizierung der Dokumente findet zudem eine sogenannte Tokenisierung statt. Für eine Maschine ist ein Dokument zunächst einmal eine Ansammlung von Informationen. Selbst wenn man sich von der Ebene der Bits löst und sich dem für Menschen lesbaren Inhalt zuwendet, besteht ein Dokument aus einer Aneinanderreihung von Zeichen: Buchstaben, Satzzeichen, Leerzeichen.
Aus dieser Datenmenge erzeugt man mit der Tokenisierung Segmente, die Begriffe (meistens einzelne Wörter), nach denen schließlich gesucht werden kann. Die einfachste Art, wie eine solche Tokenisierung ablaufen kann, funktioniert mit der White-Space-Methode: Ein Begriff endet dann, wenn ein Leerzeichen (ein weißer Zwischenraum) auftritt. Dies ist aber nicht zielführend, wenn feste Begriffe aus mehreren Wörtern bestehen, beispielsweise der „Heilige Abend“. Dafür kommen zusätzlich Wörterbücher zum Einsatz, die man auch in den Lucene-Code implementieren kann.
Bei der Analyse der Daten, von der die Tokenisierung ein Teil ist, führt Lucene zudem eine Normalisierung durch. Das heißt, die Begriffe werden in eine standardisierte Form gebracht, indem z. B. alle Großbuchstaben kleingeschrieben werden. Zudem schafft Lucene eine Sortierung. Diese funktioniert über verschiedene Algorithmen – z. B. über das TF-IDF-Maß. Als Nutzer möchte man wahrscheinlich die relevantesten oder neuesten Ergebnisse zuerst erhalten – die Algorithmen der Suchmaschine ermöglichen dies.
Damit Nutzer überhaupt etwas finden, müssen sie einen Suchbegriff in eine Textzeile eingeben. Den Begriff bzw. die Begriffe nennt man im Kontext von Lucene Query. Das englische Wort für Anfrage deutet an, dass die Eingabe eben nicht nur aus einem Wort oder mehreren bestehen muss, sondern auch Modifikatoren wie AND, OR oder auch + und - sowie Platzhalter enthalten kann. Der QueryParser – eine Klasse innerhalb der Programmbibliothek – übersetzt die Eingabe in einen konkreten Suchauftrag für die Suchmaschine. Auch beim QueryParser haben Entwickler Einstellungsmöglichkeiten. Den Parser kann man so konfigurieren, dass er genau auf die Bedürfnisse der Nutzer zugeschnitten ist.
Was Lucene bei Erscheinen komplett neu machte: die inkrementelle Indizierung. Vor Lucene war nur das sogenannte Batch-Indexing möglich. Während man damit nur komplette Indexe implementieren kann, lässt sich mit einer inkrementellen Indizierung ein Index aktualisieren. Einzelne Einträge können hinzugefügt oder entfernt werden.
Lucene ist eine Volltextsuche. Das bedeutet ganz simpel gesprochen: Ein Programm durchsucht eine Reihe von Textdokumenten nach einem oder mehreren vom Nutzer bestimmten Begriffen. Darin erkennt man schon, dass Lucene gar nicht ausschließlich im Kontext des World Wide Webs Verwendung findet – auch wenn die Suchfunktionen hier omnipräsent sind. Auch für Archive, Bibliotheken oder sogar den heimischen Desktop-PC kann man Lucene einsetzen. Lucene durchsucht nämlich nicht nur HTML-Dokumente, sondern arbeitet z. B. auch mit E-Mail oder sogar PDF-Dateien.
Ausschlaggebend für die Suche ist ein Index – das Herz von Lucene: Hier sind alle Begriffe aller Dokumente gespeichert. Ein solcher Inverted Index ist prinzipiell nur eine Tabelle – zu jedem Begriff ist die entsprechende Position gespeichert. Damit man einen Index aufbauen kann, bedarf es zunächst einer Extrahierung. Alle Begriffe müssen aus allen Dokumenten gezogen und im Index gespeichert werden. Lucene gibt Nutzern die Möglichkeit, diese Extrahierung individuell zu konfigurieren. Entwickler entscheiden sich bei der Konfiguration, welche Felder sie in den Index aufnehmen möchten. Um dies zu verstehen, muss man einen Schritt zurückgehen.
Die Objekte, mit denen Lucene arbeitet, sind Dokumente in jeglicher Form. Die Dokumente selbst enthalten aber – aus der Sichtweise von Lucene gesprochen – Felder. In diesen stehen z. B. der Name der Autorin, der Titel des Dokuments oder der Dateiname des selbigen. Jedes Feld hat eine eindeutige Bezeichnung und einen Wert. So kann das Feld mit der Bezeichnung title etwa den Wert „Gebrauchsanweisung für Apache Lucene“ haben. Beim Erstellen des Indexes kann man sich also entscheiden, welche Metadaten man aufnehmen möchte.
Bei der Indizierung der Dokumente findet zudem eine sogenannte Tokenisierung statt. Für eine Maschine ist ein Dokument zunächst einmal eine Ansammlung von Informationen. Selbst wenn man sich von der Ebene der Bits löst und sich dem für Menschen lesbaren Inhalt zuwendet, besteht ein Dokument aus einer Aneinanderreihung von Zeichen: Buchstaben, Satzzeichen, Leerzeichen.
Aus dieser Datenmenge erzeugt man mit der Tokenisierung Segmente, die Begriffe (meistens einzelne Wörter), nach denen schließlich gesucht werden kann. Die einfachste Art, wie eine solche Tokenisierung ablaufen kann, funktioniert mit der White-Space-Methode: Ein Begriff endet dann, wenn ein Leerzeichen (ein weißer Zwischenraum) auftritt. Dies ist aber nicht zielführend, wenn feste Begriffe aus mehreren Wörtern bestehen, beispielsweise der „Heilige Abend“. Dafür kommen zusätzlich Wörterbücher zum Einsatz, die man auch in den Lucene-Code implementieren kann.
Bei der Analyse der Daten, von der die Tokenisierung ein Teil ist, führt Lucene zudem eine Normalisierung durch. Das heißt, die Begriffe werden in eine standardisierte Form gebracht, indem z. B. alle Großbuchstaben kleingeschrieben werden. Zudem schafft Lucene eine Sortierung. Diese funktioniert über verschiedene Algorithmen – z. B. über das TF-IDF-Maß. Als Nutzer möchte man wahrscheinlich die relevantesten oder neuesten Ergebnisse zuerst erhalten – die Algorithmen der Suchmaschine ermöglichen dies.
Damit Nutzer überhaupt etwas finden, müssen sie einen Suchbegriff in eine Textzeile eingeben. Den Begriff bzw. die Begriffe nennt man im Kontext von Lucene Query. Das englische Wort für Anfrage deutet an, dass die Eingabe eben nicht nur aus einem Wort oder mehreren bestehen muss, sondern auch Modifikatoren wie AND, OR oder auch + und - sowie Platzhalter enthalten kann. Der QueryParser – eine Klasse innerhalb der Programmbibliothek – übersetzt die Eingabe in einen konkreten Suchauftrag für die Suchmaschine. Auch beim QueryParser haben Entwickler Einstellungsmöglichkeiten. Den Parser kann man so konfigurieren, dass er genau auf die Bedürfnisse der Nutzer zugeschnitten ist.
Was Lucene bei Erscheinen komplett neu machte: die inkrementelle Indizierung. Vor Lucene war nur das sogenannte Batch-Indexing möglich. Während man damit nur komplette Indexe implementieren kann, lässt sich mit einer inkrementellen Indizierung ein Index aktualisieren. Einzelne Einträge können hinzugefügt oder entfernt werden.
Lucene vs. Google & Co.?
Die Frage scheint berechtigt: Warum sollte man eine eigene Suchmaschine bauen, wenn es doch auch Google, Bing oder andere Search Engines gibt? Dies lässt sich natürlich nicht einfach beantworten, schließlich muss man den individuellen Anwendungswunsch betrachten. Eines ist aber wichtig zum Verständnis: Wenn wir von Lucene als Suchmaschine sprechen, ist das nur eine vereinfachte Bezeichnung.
Tatsächlich ist es eine Information Retrieval Library. Lucene ist damit ein System, mit dem Informationen gefunden werden können. Das sind Google und andere Suchmaschinen an sich auch, aber diese beschränken sich auf Informationen aus dem World Wide Web. Lucene können Sie in jedem Szenario anwenden und so konfigurieren, wie es für Ihren Zweck passend ist. So bauen Sie Lucene z. B. auch in andere Anwendungen ein.
Tatsächlich ist es eine Information Retrieval Library. Lucene ist damit ein System, mit dem Informationen gefunden werden können. Das sind Google und andere Suchmaschinen an sich auch, aber diese beschränken sich auf Informationen aus dem World Wide Web. Lucene können Sie in jedem Szenario anwenden und so konfigurieren, wie es für Ihren Zweck passend ist. So bauen Sie Lucene z. B. auch in andere Anwendungen ein.
Apaches Lucene ist im Gegensatz zu Web Search Engines keine fertige Software: Um von den Möglichkeiten des Systems profitieren zu können, müssen Sie eine eigene Suchmaschine zunächst programmieren. Wir zeigen Ihnen die ersten Schritte in unserem Lucene-Tutorial.
Lucene, Solr, Elasticsearch – wo sind die Unterschiede?
Gerade Einsteiger fragen sich, was denn eigentlich der Unterschied zwischen Apache Lucene auf der einen sowie Apache Solr und Elasticsearch auf der anderen Seite ist. Die beiden Letzteren bauen auf Lucene auf: Bei dem älteren Produkt handelt es sich um eine reine Suchmaschine. Solr und Elasticsearch hingegen stellen komplette Suchserver dar, die den Umfang von Lucene noch erweitern.
Wenn Sie nur eine Suchfunktion für Ihre Website benötigen, sind Sie wahrscheinlich mit Solr oder Elasticsearch besser bedient. Diese beiden Systeme sind konkret für den Einsatz im Web ausgelegt.
Apache Lucene – das Tutorial
Lucene basiert in der Originalversion auf Java, was es möglich macht, die Suchmaschine für verschiedene Plattformen on- und offline einzusetzen – wenn man weiß, wie es geht. Wir erklären Ihnen Schritt für Schritt, wie Sie eine eigene Suchmaschine mit Apache Lucene bauen.
In diesem Tutorial befassen wir uns mit Lucene auf der Basis von Java. Der Code wurde unter der Lucene-Version 7.3.1 und der JDK-Version 8 getestet. Wir arbeiten mit Eclipse unter Ubuntu. Einzelne Schritte können unter der Verwendung von anderen Entwicklungsumgebungen und Betriebssystemen anders verlaufen.
Installation
Damit Sie mit Apache Lucene arbeiten können, muss Java bei Ihnen installiert sein. Genau wie Lucene können Sie auch das Java Development Kit (JDK) kostenlos auf der offiziellen Website downloaden. Zudem sollten Sie noch eine Entwicklungsumgebung installieren, mit der Sie den Code für Lucene schließlich schreiben können. Viele Entwickler setzen auf Eclipse, aber es gibt noch zahlreiche andere Open-Source-Angebote. Im Anschluss können Sie Lucene von der Projektseite herunterladen. Wählen Sie hierfür die Core-Version des Programms.
Sie brauchen Lucene nicht zu installieren. Entpacken Sie den Download einfach an einen gewünschten Ort. Sie erstellen anschließend in Eclipse oder einer anderen Entwicklungsumgebung ein neues Projekt und fügen Lucene als Library hinzu. Für dieses Beispiel verwenden wir drei Bibliotheken, die alle im Installationspaket enthalten sind:
Sie brauchen Lucene nicht zu installieren. Entpacken Sie den Download einfach an einen gewünschten Ort. Sie erstellen anschließend in Eclipse oder einer anderen Entwicklungsumgebung ein neues Projekt und fügen Lucene als Library hinzu. Für dieses Beispiel verwenden wir drei Bibliotheken, die alle im Installationspaket enthalten sind:
- …/lucene-7.3.1/core/lucene-core-7.3.1.jar
- …/lucene-7.3.1/queryparser/lucene-queryparser-7.3.1.jar
- …/lucene-7.3.1/analysis/common/lucene-analyzers-common-7.3.1.jar
Ohne grundlegende Kenntnisse in Java und Programmierarbeit im Allgemeinen sind die folgenden Schritte nur schwer nachzuvollziehen. Wenn Sie allerdings schon Basiswissen in dieser Programmiersprache besitzen, ist die Arbeit mit Lucene eine gute Möglichkeit, Ihre Fähigkeiten auszubauen.
Indexierung
Das Kernstück einer Suchmaschine, die auf Lucene basiert, ist der Index. Ohne einen Index können Sie keine Suchfunktion anbieten. Deshalb ist dies der erste Schritt: Wir erstellen eine Java-Klasse für die Indexierung.
Bevor wir aber den eigentlichen Indexierungsmechanismus bauen, erstellen wir zwei Klassen, die Ihnen als Hilfe für die weiteren dienen. Sowohl die Index-Klasse als auch die Such-Klasse greifen später auf die beiden zurück.
Bevor wir aber den eigentlichen Indexierungsmechanismus bauen, erstellen wir zwei Klassen, die Ihnen als Hilfe für die weiteren dienen. Sowohl die Index-Klasse als auch die Such-Klasse greifen später auf die beiden zurück.
package tutorial;
public class LuceneConstants {
public static final String CONTENTS = "contents";
public static final String FILE_NAME = "filename";
public static final String FILE_PATH = "filepath";
public static final int MAX_SEARCH = 10;
Diese Informationen sind später wichtig, wenn es darum geht, Felder genau zu bestimmen.
package tutorial;
import java.io.File;
import java.io.FileFilter;
public class TextFileFilter implements FileFilter {
@Override
public boolean accept(File pathname) {
return pathname.getName().toLowerCase().endsWith(".txt");
}
}
Hiermit implementieren wir einen Filter, der unsere Dokumente richtig einliest. An dieser Stelle erkennen Sie auch schon, dass unsere Suchmaschine später nur für txt-Dateien funktionstüchtig ist. Alle anderen Formate ignoriert das einfache Beispiel.
Zu Beginn einer Klasse importieren Sie zunächst andere Klassen. Diese sind entweder bereits Teil Ihrer Java-Installation oder stehen Ihnen durch die Einbindung der externen Bibliotheken zur Verfügung.
Nun erstellen Sie die eigentliche Klasse für die Indexierung.
package tutorial;
import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Paths;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
public class Indexer {
private IndexWriter writer;
public Indexer(String indexDirectoryPath) throws IOException {
Directory indexDirectory =
FSDirectory.open(Paths.get(indexDirectoryPath));
StandardAnalyzer analyzer = new StandardAnalyzer();
IndexWriterConfig iwc = new IndexWriterConfig(analyzer);
writer = new IndexWriter(indexDirectory, iwc);
}
public void close() throws CorruptIndexException, IOException {
writer.close();
}
private Document getDocument(File file) throws IOException {
Document document = new Document();
TextField contentField = new TextField(LuceneConstants.CONTENTS, new FileReader(file));
TextField fileNameField = new TextField(LuceneConstants.FILE_NAME,
file.getName(),TextField.Store.YES);
TextField filePathField = new TextField(LuceneConstants.FILE_PATH,
file.getCanonicalPath(),TextField.Store.YES);
document.add(contentField);
document.add(fileNameField);
document.add(filePathField);
return document;
}
private void indexFile(File file) throws IOException {
System.out.println("Indexing "+file.getCanonicalPath());
Document document = getDocument(file);
writer.addDocument(document);
}
public int createIndex(String dataDirPath, FileFilter filter)
throws IOException {
File[] files = new File(dataDirPath).listFiles();
for (File file : files) {
if(!file.isDirectory()
&& !file.isHidden()
&& file.exists()
&& file.canRead()
&& filter.accept(file)
){
indexFile(file);
}
}
return writer.numDocs();
}
}
Im Verlauf des Codes werden verschiedene Schritte durchgeführt: Sie stellen den IndexWriter mithilfe des StandardAnalyzers ein. Lucene bietet unterschiedliche Analyse-Klassen, die Sie alle in der entsprechenden Bibliothek finden.
In der Dokumentation von Apache Lucene finden Sie alle Klassen, die im Download enthalten sind.
Des Weiteren liest das Programm Dateien ein und legt Felder für die Indexierung fest. Zum Ende des Codes werden schließlich die Index-Dateien erzeugt.
Suchfunktion
Natürlich bringt Ihnen der Index allein nichts. Sie müssen also auch noch eine Suchfunktion etablieren.
package tutorial;
import java.io.IOException;
import java.nio.file.Paths;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
public class Searcher {
IndexSearcher indexSearcher;
QueryParser queryParser;
Query query;
public Searcher(String indexDirectoryPath)
throws IOException {
Directory indexDirectory =
FSDirectory.open(Paths.get(indexDirectoryPath));
IndexReader reader = DirectoryReader.open(indexDirectory);
indexSearcher = new IndexSearcher(reader);
queryParser = new QueryParser(LuceneConstants.CONTENTS,
new StandardAnalyzer());
}
public TopDocs search( String searchQuery)
throws IOException, ParseException {
query = queryParser.parse(searchQuery);
return indexSearcher.search(query, LuceneConstants.MAX_SEARCH);
}
public Document getDocument(ScoreDoc scoreDoc)
throws CorruptIndexException, IOException {
return indexSearcher.doc(scoreDoc.doc);
}
}
Zwei von Lucene importierte Klassen sind innerhalb des Codes besonders wichtig: IndexSearcher und QueryParser. Während ersteres den erstellten Index durchsucht, ist QueryParser dafür zuständig, die Suchanfrage überhaupt in eine für die Maschine verständliche Information zu transferieren.
Nun haben Sie sowohl eine Klasse zur Indexierung als auch eine, um den Index zu durchsuchen, aber einen konkreten Suchauftrag können Sie mit beiden noch nicht durchführen. Deshalb brauchen Sie nun noch eine fünfte Klasse.
Nun haben Sie sowohl eine Klasse zur Indexierung als auch eine, um den Index zu durchsuchen, aber einen konkreten Suchauftrag können Sie mit beiden noch nicht durchführen. Deshalb brauchen Sie nun noch eine fünfte Klasse.
package tutorial;
import java.io.IOException;
import org.apache.lucene.document.Document;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
public class LuceneTester {
String indexDir = "/home/Index/";
String dataDir = "/home/Data/";
Indexer indexer;
Searcher searcher;
public static void main(String[] args) {
LuceneTester tester;
try {
tester = new LuceneTester();
tester.createIndex();
tester.search("YourSearchTerm");
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
private void createIndex() throws IOException {
indexer = new Indexer(indexDir);
int numIndexed;
long startTime = System.currentTimeMillis();
numIndexed = indexer.createIndex(dataDir, new TextFileFilter());
long endTime = System.currentTimeMillis();
indexer.close();
System.out.println(numIndexed+" File indexed, time taken: "
+(endTime-startTime)+" ms");
}
private void search(String searchQuery) throws IOException, ParseException {
searcher = new Searcher(indexDir);
long startTime = System.currentTimeMillis();
TopDocs hits = searcher.search(searchQuery);
long endTime = System.currentTimeMillis();
System.out.println(hits.totalHits +
" documents found. Time :" + (endTime - startTime));
for(ScoreDoc scoreDoc : hits.scoreDocs) {
Document doc = searcher.getDocument(scoreDoc);
System.out.println("File: "
+ doc.get(LuceneConstants.FILE_PATH));
}
}
}
Mindestens drei Einträge in dieser finalen Klassen müssen Sie anpassen, denn hier geben Sie die Pfade zu den Originaldokumenten und zu den Indexdateien an sowie schließlich auch das Suchwort.
Um das Programm zu testen, kopieren Sie einige Klartext-Dateien in das als dataDir angegebene Verzeichnis. Achten Sie darauf, dass die Dateiendungen „.txt“ lauten. Nun können Sie das Programm starten – in Eclipse etwa klicken Sie dafür den grünen Pfeil-Button in der Menüleiste an.
- String indexDir: Hier fügen Sie den Pfad zu dem Ordner ein, in dem Sie die Indexdateien speichern möchten.
- String dataDir: An dieser Stelle erwartet der Quelltext den Pfad zum Ordner, in dem die zu durchsuchenden Dokumente gespeichert sind.
- tester.search: Hier tragen Sie Ihren Suchbegriff ein.
Um das Programm zu testen, kopieren Sie einige Klartext-Dateien in das als dataDir angegebene Verzeichnis. Achten Sie darauf, dass die Dateiendungen „.txt“ lauten. Nun können Sie das Programm starten – in Eclipse etwa klicken Sie dafür den grünen Pfeil-Button in der Menüleiste an.
Bei dem vorgestellten Programmcode handelt es sich nur um ein Demo-Projekt, um die Wirkungsweise von Lucene zu präsentieren. Beispielsweise fehlt in diesem Programm eine grafische Benutzeroberfläche: Den Suchbegriff müssen Sie direkt in den Quelltext eintragen und das Ergebnis erhalten Sie nur über die Konsole.
Lucene Query Syntax
Suchmaschinen – auch die, die Sie aus dem Web kennen – lassen meist nicht nur die Suche nach einem einzelnen Begriff zu. Mit bestimmten Methoden können Sie Begriffe aneinanderreihen, nach Phrasen suchen oder einzelne Wörter ausschließen. Selbstverständlich bietet auch Apache Lucene diese Möglichkeiten: Mit der Lucene Query Syntax suchen Sie nach komplexen Ausdrücken – auch in mehreren Feldern.
- Single Term: Einen einfachen Begriff geben Sie so ein, wie dieser lautet. Anders als Google und Co. geht Lucene davon aus, dass Sie wissen, wie der Begriff geschrieben wird. Sollten Sie einen Schreibfehler einbauen, erhalten Sie auch ein negatives Ergebnis. Beispiel: Auto
- Phrase: Als Phrasen gelten festgelegte Wortfolgen. Dabei sind nicht nur die einzelnen Begriffe innerhalb der Phrase entscheidend, sondern auch die Reihenfolge, in der diese stehen. Beispiel: "Mein Auto ist rot"
- Wildcard Searches: Mit Platzhaltern ersetzen Sie einen oder mehrere Zeichen in Ihrer Suchanfrage. Wildcards lassen sich sowohl am Ende als auch in der Mitte eines Begriffs einsetzen, allerdings nicht am Anfang.
- ?: Das Fragezeichen steht genau für ein Zeichen. Beispiel: Au?o
- *: Das Sternchen ersetzt gar keinen oder unendlich viele Zeichen. So lassen sich z. B. auch andere Formen eines Begriffs suchen, etwa der Plural. Beispiel: Auto*
- ?: Das Fragezeichen steht genau für ein Zeichen. Beispiel: Au?o
- Regular Expression Searches: Mit regulären Ausdrücken suchen Sie nach mehreren Begriffen gleichzeitig, die teilweise Gemeinsamkeiten haben und teilweise voneinander abweichen. Im Gegensatz zu Wildcards definieren Sie genau, welche Abweichungen berücksichtigt werden sollen. Dafür nutzen Sie Schrägstriche und eckige Klammern. Beispiel: /[MS]ein/
- Fuzzy Searches: Eine unscharfe Suche führen Sie dann durch, wenn Sie beispielsweise eine Fehlertoleranz haben möchten. Mithilfe der Damerau-Levenshtein-Distanz (eine Formel, die Ähnlichkeiten bewertet), stellen Sie ein, wie groß die Abweichung sein darf. Hierfür nutzen Sie die Tilde. Distanzen von 0 bis 2 sind zugelassen. Beispiel: Auto~1
- Proximity Searches: Auch wenn Sie eine Näherung bei Phrasen zulassen möchten, nutzen Sie die Tilde. So können Sie beispielsweise angeben, dass Sie zwei Begriffe auch dann suchen, wenn zwischen diesen 5 andere Wörter vorkommen. Beispiel: "Auto rot"~5
- Range Searches: Bei dieser Form der Anfrage suchen Sie in einem bestimmten Bereich zwischen zwei Begriffen. Während eine solche Suche für den generellen Inhalt eines Dokuments wenig sinnvoll ist, kann sie sehr nützlich im Umgang mit bestimmten Feldern wie Autoren oder Titeln sein. Die Sortierung funktioniert nach einer lexikografischen Ordnung. Während Sie einen inklusiven Bereich mit eckigen Klammern verdeutlichen, schließen Sie mit geschweiften Klammern den durch die beiden Suchbegriffe bestimmten Bereich aus der Anfrage aus. Die beiden Begriffe grenzen Sie mit TO ab. Beispiel: [Allende TO Borges] bzw. {Byron TO Shelley}
- Boosting: Lucene gibt Ihnen die Möglichkeit, einzelnen Begriffen oder Phrasen mehr Relevanz bei der Suche zu geben als anderen. Damit beeinflussen Sie die Sortierung der Ergebnisse. Den Boosting-Faktor legen Sie mit dem Zirkumflex gefolgt von einem Wert fest. Beispiel: Auto^2 rot
- Boolean Operators: Mit logischen Operatoren stellen Sie Verbindungen zwischen Begriffen innerhalb einer Suchanfrage her. Die Operatoren müssen immer in Großbuchstaben geschrieben werden, damit Lucene diese nicht als normale Suchbegriffe wertet.
- AND: Bei einer Und-Verknüpfung müssen zwingend beide Begriffe im Dokument vorkommen, damit dieses als Ergebnis auftaucht. Statt dem Ausdruck können Sie auch zwei aufeinanderfolgende kaufmännische Und-Zeichen verwenden. Beispiel: Auto && rot
- OR: Die Oder-Verknüpfung ist der Standardfall, wenn Sie einfach zwei Begriffe nacheinander einfügen. Einer der beiden Begriffe muss zwingend vorkommen, es können aber auch beide gemeinsam im Dokument enthalten sein. Sie erstellen die Oder-Verknüpfung mit OR, || oder indem Sie gar keinen Operator eingeben. Beispiel: Auto rot
- +: Mit dem Plus-Zeichen bauen Sie einen bestimmten Fall der Oder-Verknüpfung auf. Setzen Sie das Zeichen direkt vor ein Wort, muss dieser Begriff vorkommen, während der andere optional ist. Beispiel: +Auto rot
- NOT: Die Nicht-Verknüpfung schließt bestimmte Begriffe oder Phrasen aus der Suche aus. Sie können den Operator durch ein Ausrufezeichen ersetzen oder ein Minus direkt vor den auszuschließenden Begriff setzen. Den NOT-Operator dürfen Sie nicht mit nur einem einzigen Begriff bzw. nur einer Phrase verwenden. Beispiel: Auto rot -blau
- AND: Bei einer Und-Verknüpfung müssen zwingend beide Begriffe im Dokument vorkommen, damit dieses als Ergebnis auftaucht. Statt dem Ausdruck können Sie auch zwei aufeinanderfolgende kaufmännische Und-Zeichen verwenden. Beispiel: Auto && rot
- Grouping: Mit Klammern lassen sich Begriffe innerhalb von Suchanfragen gruppieren. So erstellen Sie komplexere Eingaben, mit denen Sie z. B. einen Begriff zwingend mit einem von zwei Begriffen koppeln: Auto UND (rot ODER blau)
- Escaping Special Characters: Um Zeichen, die für die Lucene Query Syntax verwendbar sind, in Suchbegriffen zu nutzen, kombinieren Sie diese mit einem Backslash. So bauen Sie etwa ein Fragezeichen in eine Suchanfrage ein, ohne dass der Parser dieses als Wildcard interpretiert: "Wo ist mein Auto\?"
Apache Lucene: Vor- und Nachteile
Lucene ist ein mächtiges Werkzeug, um im Web, in Archiven oder in Anwendungen eine Suchfunktion zu etablieren. Fans von Lucene genießen es, durch die Indexierung eine sehr schnelle Suchmaschine bauen zu können, die zudem sehr detailliert an die eigenen Anforderungen angepasst werden kann. Da es sich um ein Open-Source-Projekt handelt, ist Lucene nicht nur kostenlos verfügbar, sondern wird auch von einer großen Community stetig weiterentwickelt.
So kann man es außer in Java inzwischen auch in PHP, Python und anderen Programmiersprachen verwenden. Und damit kommt man auch zum eigentlich einzigen Nachteil: Programmierkenntnisse sind definitiv nötig. Die Volltextsuche ist somit nicht für jeden das Richtige. Wer nur eine Suchfunktion für seine Website braucht, ist bei anderen Angeboten sicherlich besser aufgehoben.
So kann man es außer in Java inzwischen auch in PHP, Python und anderen Programmiersprachen verwenden. Und damit kommt man auch zum eigentlich einzigen Nachteil: Programmierkenntnisse sind definitiv nötig. Die Volltextsuche ist somit nicht für jeden das Richtige. Wer nur eine Suchfunktion für seine Website braucht, ist bei anderen Angeboten sicherlich besser aufgehoben.
Vorteile | Nachteile |
Verfügbar für verschiedene Programmiersprachen | Benötigt Programmierkenntnisse |
Open Source | |
Schnell und schlank | |
Ranked Searching | |
Komplexe Suchanfragen möglich | |
Sehr flexibel |