Eine automatische Indexierung mittels Software, generiert die Schlagworte aus dem Text / Dokument heraus. Neben den Schlagworten ( =Deskriptoren) beachten Indexierer auch die Häufigkeit des Vorkommens eines Schlagwortes (= Gewichtung). Eine Suchmaschine, wie die allwissende Müllhalde names Google, erstellt permanent und endlos einen Index der Dokumente im Web. Eine Suchanfrage bewirkt ein Durchsuchen des Indexes nach den Begriffen aus der Suchanfrage.
Für den ganzen RUS Web Server und das BI Archiv habe ich dann 1993 oder 1994 eine Suchfunktion implementiert - mittels eines "Information Retrieval System" (heute = Search Engine) namens HARVEST. HARVEST war in C und PERL geschrieben, es stammte von irgend einer Uni aus USA , und die Doku war LaTeX (!!) geschrieben. Das damalige Logo sagt viel ...
Im Prinzip war alles da, was später Google groß gemacht hat - allerdings im universitären Umfeld, und ohne jeden kommerziellen Gedanken. Ich hab die Suchmaschine auch auf der ersten Web Site von Daimler-Benz installiert, und musste damals dazu extra nach Untertürkheim ins Werk fahren. Als Indexierer war HARVEST brauchbar, und ich habe viel über die Auswahl von Deskriptoren, simple Textanalyse, Volltextsuche, Stoppwörter und den Aufbau eines Indexes gelernt.
Das Arbeiten mit den jar File war nicht ganz straight forward, man braucht doch in Summe fünf *.jar Files:
import org.apache.lucene.*;
...
String indexPath = "/Users/eathanassiou/myWWW/prod/Index"; // Zielverzeichnis für den Index
Directory directory = FSDirectory.open(Paths.get(indexPath));
IndexWriterConfig config = new IndexWriterConfig(new StandardAnalyzer());
IndexWriter writer = new IndexWriter(directory, config);
...
Path file = new Path(""/Users/eathanassiou/myWWW/prod/BeispielDatei.txt";");
addFileToIndex(writer, file);
....
private static void addFileToIndex(IndexWriter writer, Path filePath) throws IOException {
String absPath = filePath.toAbsolutePath().toString();
Document document = new Document();
Reader reader = new InputStreamReader(new FileInputStream(absPath), "UTF-8");
document.add(new TextField("contents", reader));
StringField sf = new StringField("pathname", absPath, Field.Store.YES );
document.add(sf);
writer.addDocument(document);
}
Der Code braucht jetzt aber schon noch ein paar Erläuterungen ... in ihm wurde der Constructor new StandardAnalyzer() verwendet um einen
IndexWriter zu konfigurieren. Mit dem Analyzer wird festgelegt wie die Dateien indexiert werden,
d.h. Einstellungen zum Parsen, der Stammformbildung und Stoppwortlisten werden vorgenommen. StandardAnalyzer() ist ein englischsprachiger Parser mit einer
Standardstoppwortliste. Lucene verfügt über einige weitere Analyzer. Für unterschiedliche Anforderungen, verwendet man verschiedene Analyzer.
Das Lucene-Analyzers-Common-Modul enthält alle genannten Komponenten,
Die am häufigsten verwendeten Analysatoren finden sich im Paket org.apache.lucene.analysis..
Sprachspezifische Analysatoren finden sich in den packages org.apache.lucene.analysis {Sprachcode} .
KEYWORD IPTC -Tag zur Suche in seinem "Finder". Ich habe das mit den Tags zur Indexierung angeschaut, und dann sein lassen.
Verwendet habe ich den Dateinamen gemäß der in dem vorherigen Kapitel beschrieben Namenskonvention. Der Grund war kein technischer, sondern ein rein praktischer.t.
Es fehlten doch einige Wagen, und bei den manuell oder semiautomatisch beschafften Dateinen ist einfach schneller, den Dateinamen zu ändern als mühsam die IPTC Tags
neu zu setzen. Das eine geht auf OS-Ebene, das andere ist Software, gerade beim Entwickeln geht es mit Dateinamen schneller - vor allem bei Sichtkontrollen und Korrekturen.
Zur Umsetzung war aber ein kleiner Kniff nötig. Dem Lucene Indexierer musste die Existenz einer Datei, mit den einzelnen Elementen des Dateinamen als Inhalt "vorgegaukelt" werden. Aber das ging prima mit einer temporären Datei.
private static void addFileToIndex(IndexWriter writer, Path filePath) throws IOException {
String fileName = filePath.getFileName().toString();
String absPath = filePath.toAbsolutePath().toString();
Document document = new Document();
String tmpFile = "/Users/eathanassiou/myWWW/prod/tmp/tmp.data"; //Erzeugen des temporären Files
String f = fileName.replace(".jpg","");
String[] tokens = f.split("_");
appendToFile(tmpFile, tokens); // Elemente des Dateinamens als einzelne Zeilen in der Datei
Reader reader = new InputStreamReader(new FileInputStream(tmpFile), "UTF-8");
document.add(new TextField("contents", reader));
deleteFile(tmpFile);
StringField sf = new StringField("filename", fileName, Field.Store.YES );
document.add(sf);
StringField sf2 = new StringField("pathname", absPath, Field.Store.YES );
document.add(sf2);
writer.addDocument(document);
}
TextField was gesucht werden soll, in der Regel ist das der String "content".
...
final String iField ="contents";
searchFiles(String indexPath, String iField, "Piquet", 100) {
...
public static List searchFiles(String indexPath, String inField, String queryString, int Anz) {
try {
StandardAnalyzer analyzer = new StandardAnalyzer();
Query query = new QueryParser(inField, analyzer).parse(queryString);
Directory directory = FSDirectory.open(Paths.get(indexPath));
IndexReader reader = DirectoryReader.open(directory);
IndexSearcher searcher = new IndexSearcher(reader);
TopDocs topDocs = searcher.search(query, Anz);
List results = new ArrayList<>();
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
Document document = searcher.doc(scoreDoc.doc); //
results.add(document.get("pathname") );
}
return results;
} catch (IOException | ParseException e) {
e.printStackTrace();
}
return null;
}
Lucene ist ein Indexierer, das heist es liefert die Dokumenten als Ergebnis wieder , die der Anfrage am ehesten entsprechen.
Bei der Indexierung von Attributen aus Dateinamen(wie in meiner Anwendung) benutzt man Lucene etwas unter den Möglichkeiten des Systems, aber das kann ja noch kommen ...