14.2. Indexerstellung

14.2.1. Einen neuen Index erstellen

Die Funktionen für das Erstellen und Aktualisieren eines Index wurden innerhalb der Zend_Search_Lucene Komponente und von Java Lucene implementiert. Du kannst diese beiden Funktionalitäten verwenden.

Der PHP Quellcode unten zeigt ein Beispiel, wie eine Datei durch Verwendung der Zend_Search_Lucene Programmierschnittstelle (API) indiziert werden kann:

<?php

// Das Setzen des zweiten Arguments auf TRUE erstellt einen neuen Index
$index = new Zend_Search_Lucene('/data/my-index', true);

$doc = new Zend_Search_Lucene_Document();

// Speichere die URL des Dokuments, um es für Suchergebnisse ermitteln zu können
$doc->addField(Zend_Search_Lucene_Field::Text('url', $docUrl));

// Indiziere den Dokumenteninhalt
$doc->addField(Zend_Search_Lucene_Field::UnStored('contents', $docContent));

// Füge das Dokument dem Index hinzu 
$index->addDocument($doc);

// Schreibe die Änderungen in den Index.
$index->commit();
?>

Neu hinzugefügte Dokumente können nach der Übergabe aus dem Index zurückgeholt werden.

Zend_Search_Lucene::commit() wird automatisch am Ende der Skriptausführung vor jeder Suchanfrage aufgerufen.

Jeder commit() Aufruf erstellt ein neues Indexsegment. [6] Also muß er so selten wie möglich aufgerufen werden. Auf der anderen Seite verbraucht die Verarbeitung sehr vieler Dokumente in einem Schritt auch mehr Speicher..

Die automatische Optimierung von Segmenten ist ein Thema für zukünftige Weiterentwicklungen von Zend_Search_Lucene.

14.2.2. Indexaktualisierung

Der selbe Prozess wird verwendet, um einen vorhandenen Index zu aktualisieren. Der einzige Unterschied ist, dass der Index ohne den zweiten Parameter geöffnet werden sollte:

<?php

// Öffnen einen vorhandenen Index
$index = new Zend_Search_Lucene('/data/my-index');

$doc = new Zend_Search_Lucene_Document();

// Speichere die URL des Dokuments, um es für Suchergebnisse ermitteln zu können
$doc->addField(Zend_Search_Lucene_Field::Text('url', $docUrl));

// Indiziere den Dokumenteninhalt
$doc->addField(Zend_Search_Lucene_Field::UnStored('contents', $docContent));

// Füge das Dokument dem Index hinzu 
$index->addDocument($doc);

// Schreibe die Änderungen in den Index.
$index->commit();
?>

Jeder Aufruf von commit() (explizit oder implizit) erstellt ein neues Indexsegment.

Zend_Search_Lucene kann Segmente nicht automatisch verwalten. Deshalb solltest du dich um die Segmentgröße kümmer. Auf der einen Seite sind große Segmente optimaler, auf der anderen Seite verbrauchen große Segmente beim Erstellen mehr Speicher.

Lucene Java and Luke (Lucene Index Toolbox - http://www.getopt.org/luke/) können für die Indexoptimierung dieser Zend_Search_Lucene Version verwendet werden.

14.2.3. Dokumente aktualisieren

Das Lucene Indexdateiformat unterstützt keine Aktualisierung von Dokumenten. Ein Dokument sollte entfernt und wieder hinzugefügt werden, um eine Aktualisierung zu erreichen.

Die Zend_Search_Lucene::delete() Methode arbeitet mit einer internen Index Dokumentennummer. Sie kann aus dem Ergebnistreffer über die 'id' Eigenschaft erhalten werden:

<?php
$removePath = ...;
$hits = $index->find('path:' . $removePath);
foreach ($hits as $hit) {
    $index->delete($hit->id);
}
$index->commit();
?>


[6] Lucene Indexsegment Dateien können aufgrund ihrer Eigenschaft nicht aktualisiert werden. Eine Segmentaktualisierung benötigt einen Neuaufbau des kompletten Segments. Beachte die Indexdateiformate von Lucene für weitere Einzelheiten (http://lucene.apache.org/java/docs/fileformats.html). Eine steigende Anzahl von Segmenten vermindert die Qualität des Index, aber die Indexoptimierung stellt diese wieder her. Die Optimierung ist darauf beschränkt, mehrere Segmente in ein einziges zusammenzufassen. Dieser Prozess aktualisiert die Segmente zude nicht. Es erstellt ein neues großes Segment, erstellt eine neue Segmentliste ('segments.new' Datei), welche das neue optimierte Segment anstelle der alten Segmente enthält, und benennt dann die 'segments.new' Datei in 'segments' um.

Die Optimierung ist ein sich wiederholender Prozess. Sehr kleine Segmente (die beim Hinzufügen eines einzelnen Dokuments entstehen) werden in größere Segmente zusammengefasst und so weiter. Die Optimierung kann mit einer Kette von Dokumenten arbeiten und verbraucht nicht viel Speicher. Dadurch verbraucht der Optimierungsprozess nicht viele Ressourcen und sperrt den Index nicht für das Suchen, Aktualisieren und Zusammenfassen anderer Segmente.