27.2. Indexerstellung

27.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

// Index erstellen
$index = Zend_Search_Lucene::create('/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);
?>

Neu hinzugefügte Dokumente können sofort aus einem Index zurückgeholt werden.

27.2.2. Indexaktualisierung

Der selbe Prozess wird verwendet, um einen vorhandenen Index zu aktualisieren. Der einzige Unterschied ist, dass die open() Methode statt der create() Methode aufgerufen wird:

<?php

// Öffnen einen vorhandenen Index
$index = Zend_Search_Lucene::open('/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);
?>

27.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);
}
?>

27.2.4. Retrieving Index size

There are two methods to retrieve index size in Zend_Search_Lucene.

Zend_Search_Lucene::maxDoc() returns one greater than the largest possible document number. It's actually overall number of the documents in the index including deleted documents. So it has a synonym: Zend_Search_Lucene::count().

Zend_Search_Lucene::numDocs() returns the total number of non-deleted documents.

<?php
$indexSize = $index->count();
$documents = $index->numDocs();
?>

Zend_Search_Lucene::isDeleted($id) method may be used to check if document is deleted.

<?php
for ($count = 0; $count < $index->maxDoc(); $count++) {
    if ($index->isDeleted($count)) {
        echo "Document #$id is deleted.\n";
    }
}
?>

Index optimization removes deleted documents and squeezes documents' IDs. So internal document id may be changed.

27.2.5. Indexoptimierung

Ein Lucene Index besteht aus Segmenten. Jedes Segment ist ein komplett unabhängiger Datensatz.

Lucene Indexsegmentdateien können aufgrund ihrer Natur nicht aktualisiert werden. Eine Segmentaktualisierung benötigt eine komplette Reorganisation der Segmente. Siehe auch die Lucene Indexdateiformate für weitere Details (http://lucene.apache.org/java/docs/fileformats.html). Deshalb werden neue Dokumente durch Erstellen neuer Segmente zum Index hinzugefügt.

Eine steigende Anzahl an Segmente verringert die Qualität des Index, aber die Indexoptimierung stellt diese wieder her. Die Optimierung beschränkt sich darauf, mehrere Segmente zu einem zusammen zu fassen. Dieser Prozess aktualisiert die Segmente ebenfalls nicht. Er erstellt neue große Segmente, welche ein neues optimiertes Segment anstatt einen Satz alte Segmente enthalten, und aktualisiert die Segmentenliste ('segments' Datei).

Eine komplette Indexoptimierung kann durch einen Aufruf von Zend_Search_Lucene::optimize() gestartet werden. Sie fügt alle Segmente in ein größeres zusammen.

<?php
// Öffne bestehenden Index
$index = new Zend_Search_Lucene('/data/my-index');

// Optimiere Index
$index->optimize();
?>

Die automatische Indexoptimierung wird durchgeführt, um einen Index konsistens zu halten.

Die automatische Indexoptimierung ist ein schrittweise Prozess, der durch verschiedene Indexoptionen gesteuert wird. Sie fasst sehr kleine Segmente in größere zusammen und fasst die größeren Segmente dann in noch größere zusammen und so weiter.

27.2.5.1. MaxBufferedDocs Option für automatische Optimierung

MaxBufferedDocs ist die minimale Anzahl an Dokumenten, die erforderlich ist, damit die im Hauptspeicher zwischen gespeicherten Dokumente in ein neues Segment geschrieben werden.

MaxBufferedDocs kann abgefragt bzw. gesetzt werden durch Aufrufe von $index->getMaxBufferedDocs() oder $index->setMaxBufferedDocs($maxBufferedDocs).

Standardwert is 10.

27.2.5.2. MaxMergeDocs Option für automatische Optimierung

MaxMergeDocs ist die höchste Anzahl an Dokumenten, die jemals mit addDocument() zusammengefasst werden kann. Kleine Werte (z.B. unter 10.000) sind für die interaktive Indizierung am besten, da dies die Pausen für das Indizieren auf wenige Sekunden begrenzen. Größere Werte sind am besten für Stapelverarbeitung oder schnellere Suchabfragen.

MaxMergeDocs kann abgefragt bzw. gesetzt werden durch Aufrufe von $index->getMaxMergeDocs() oder $index->setMaxMergeDocs($maxMergeDocs).

Standardwert ist PHP_INT_MAX.

27.2.5.3. MergeFactor Option für automatische Optimierung

MergeFactor legt fest, wie oft Segmentenindixes durch addDocument() zusammengefasst werden sollen. Bei kleineren Werten wird beim Indizieren weniger RAM verbraucht und Suchabfragen auf nicht optimierte Indizes sind schneller, aber die Indizierungsgeschwindigkeit ist langsamer. Bei größeren Werten, wird mehr beim Indizieren RAM verbraucht und während Suchabfragen auf nicht optimierte Indizes langsamer sind, ist das Indizieren schneller. Deshalb sind größere Werte (> 10) am besten für Stapelverarbeitung und kleinere Werte (< 10) sind besser für Indizes, die interaktiv gepflegt werden.

MergeFactor is a good estimation for average number of segments merged by one auto-optimization pass. Too large values produce large number of segments while they are not merged into new one. It may be a cause of "failed to open stream: Too many open files" error message. This limitation is system dependant.

MergeFactor kann abgefragt bzw. gesetzt werden durch Aufrufe von $index->getMergeFactor() oder $index->setMergeFactor($mergeFactor).

Standardwert ist 10.

Lucene Java und Luke (Lucene Index Toolbox - http://www.getopt.org/luke/) können auch für die Optimierung eines Index verwendet werden.

27.2.6. Einschränkungen

Einschränkungen sind Plattform abhängig.

Die maximale Indexgröße auf 32-bit Plattformen beträgt 2GB.