Las capacidades de creación y actualización de índices están implementadas dentro del
componente Zend_Search_Lucene, así como en el proyecto Java Lucene.
Puede usar cualquiera de estas opciones para crear índices que
Zend_Search_Lucene pueda buscar.
El siguiente listado de código PHP muestra un ejemplo de cómo indexar un archivo
usando la API de indexación de Zend_Search_Lucene:
// Create index
$index = Zend_Search_Lucene::create('/data/my-index');
$doc = new Zend_Search_Lucene_Document();
// Store document URL to identify it in the search results
$doc->addField(Zend_Search_Lucene_Field::Text('url', $docUrl));
// Index document contents
$doc->addField(Zend_Search_Lucene_Field::UnStored('contents', $docContent));
// Add document to the index
$index->addDocument($doc);
Los documentos recién añadidos son inmediatamente buscables en el índice.
Se utiliza el mismo procedimiento para actualizar un índice existente. La única diferencia es que se llama al método open() en lugar del método create():
// Open existing index
$index = Zend_Search_Lucene::open('/data/my-index');
$doc = new Zend_Search_Lucene_Document();
// Store document URL to identify it in search result.
$doc->addField(Zend_Search_Lucene_Field::Text('url', $docUrl));
// Index document content
$doc->addField(Zend_Search_Lucene_Field::UnStored('contents',
$docContent));
// Add document to the index.
$index->addDocument($doc);
El formato de archivo de índice de Lucene no soporta la actualización de documentos. Los documentos deben eliminarse y volver a añadirse al índice para actualizarlos de forma efectiva.
El método Zend_Search_Lucene::delete() opera con un id de documento
interno del índice. Puede obtenerse de un resultado (hit) de consulta mediante la propiedad 'id':
$removePath = ...;
$hits = $index->find('path:' . $removePath);
foreach ($hits as $hit) {
$index->delete($hit->id);
}
Hay dos métodos para obtener el tamaño de un índice en
Zend_Search_Lucene.
Zend_Search_Lucene::maxDoc() devuelve un número mayor que el
mayor número de documento posible. En realidad es el número total de documentos en
el índice incluyendo los documentos eliminados, por lo que tiene un sinónimo:
Zend_Search_Lucene::count().
Zend_Search_Lucene::numDocs() devuelve el número total de
documentos no eliminados.
$indexSize = $index->count(); $documents = $index->numDocs();
El método Zend_Search_Lucene::isDeleted($id) puede usarse para comprobar
si un documento está eliminado.
for ($count = 0; $count < $index->maxDoc(); $count++) {
if ($index->isDeleted($count)) {
echo "Document #$id is deleted.\n";
}
}
La optimización del índice elimina los documentos eliminados y comprime los IDs de los documentos en un rango más pequeño. Por lo tanto, el id interno de un documento puede cambiar durante la optimización del índice.
Un índice de Lucene consiste en muchos segmentos. Cada segmento es un conjunto de datos completamente independiente.
Los archivos de segmento del índice de Lucene no se pueden actualizar por diseño. Una actualización de un segmento requiere una reorganización completa del segmento. Consulte los formatos de archivo de índice de Lucene para más detalles (http://lucene.apache.org/java/2_3_0/fileformats.html) [10]. Los documentos nuevos se añaden al índice creando un nuevo segmento.
El aumento del número de segmentos reduce la calidad del índice, pero la optimización del índice la restaura. La optimización básicamente fusiona varios segmentos en uno nuevo. Este proceso tampoco actualiza los segmentos. Genera un nuevo segmento grande y actualiza la lista de segmentos (archivo 'segments').
La optimización completa del índice puede activarse llamando al método
Zend_Search_Lucene::optimize(). Fusiona todos los
segmentos del índice en un nuevo segmento:
// Open existing index
$index = Zend_Search_Lucene::open('/data/my-index');
// Optimize index.
$index->optimize();
La optimización automática del índice se realiza para mantener los índices en un estado consistente.
La optimización automática es un proceso iterativo gestionado por varias opciones del índice. Fusiona segmentos muy pequeños en otros más grandes, luego fusiona estos segmentos más grandes en segmentos aún más grandes, y así sucesivamente.
MaxBufferedDocs es el número mínimo de documentos requeridos antes de que los documentos almacenados en memoria (buffer) se escriban en un nuevo segmento.
MaxBufferedDocs puede obtenerse o establecerse mediante las llamadas
$index->getMaxBufferedDocs() o
$index->setMaxBufferedDocs($maxBufferedDocs).
El valor por defecto es 10.
MaxMergeDocs es el mayor número de documentos que puede fusionar addDocument(). Valores pequeños (p. ej., menos de 10.000) son los mejores para la indexación interactiva, ya que esto limita la duración de las pausas durante la indexación a unos pocos segundos. Valores más grandes son mejores para la indexación por lotes y búsquedas más rápidas.
MaxMergeDocs puede obtenerse o establecerse mediante las llamadas
$index->getMaxMergeDocs() o
$index->setMaxMergeDocs($maxMergeDocs).
El valor por defecto es PHP_INT_MAX.
MergeFactor determina con qué frecuencia se fusionan los índices de segmento mediante addDocument(). Con valores más pequeños, se usa menos RAM durante la indexación, y las búsquedas en índices no optimizados son más rápidas, pero la velocidad de indexación es más lenta. Con valores más grandes, se usa más RAM durante la indexación, y aunque las búsquedas en índices no optimizados son más lentas, la indexación es más rápida. Por lo tanto, valores más grandes (> 10) son los mejores para la creación de índices por lotes, y valores más pequeños (< 10) para índices que se mantienen de forma interactiva.
MergeFactor es una buena estimación del número medio de segmentos fusionados en un pase de auto-optimización. Valores demasiado grandes producen un número elevado de segmentos mientras no se fusionan en uno nuevo. Puede ser causa del mensaje de error "failed to open stream: Too many open files". Esta limitación depende del sistema.
MergeFactor puede obtenerse o establecerse mediante las llamadas
$index->getMergeFactor() o
$index->setMergeFactor($mergeFactor).
El valor por defecto es 10.
Lucene Java y Luke (Lucene Index Toolbox - http://www.getopt.org/luke/) también pueden
usarse para optimizar un índice. La última versión de Luke (v0.8) está basada en Lucene v2.3 y
es compatible con la implementación actual del componente Zend_Search_Lucene
(Zend Framework 1.6). Las versiones anteriores de las implementaciones de
Zend_Search_Lucene necesitan otras versiones de las herramientas
Java Lucene para ser compatibles:
Zend Framework 1.5 - Java Lucene 2.1 (herramienta Luke v0.7.1 - http://www.getopt.org/luke/luke-0.7.1/)
Zend Framework 1.0 - Java Lucene 1.4 - 2.1 (herramienta Luke v0.6 - http://www.getopt.org/luke/luke-0.6/)
Por defecto, los archivos de índice están disponibles para lectura y escritura por parte de todos.
Es posible sobrescribir esto con el método
Zend_Search_Lucene_Storage_Directory_Filesystem::setDefaultFilePermissions():
// Get current default file permissions
$currentPermissions =
Zend_Search_Lucene_Storage_Directory_Filesystem::getDefaultFilePermissions();
// Give read-writing permissions only for current user and group
Zend_Search_Lucene_Storage_Directory_Filesystem::setDefaultFilePermissions(0660);
El tamaño del índice está limitado a 2GB para plataformas de 32 bits.
Use plataformas de 64 bits para índices más grandes.
Zend_Search_Lucene usa flock() para
proporcionar búsqueda concurrente, actualización de índices y optimización.
Según la documentación de PHP,
"flock() no funcionará en NFS y muchos otros sistemas de archivos
en red".
No use sistemas de archivos en red con Zend_Search_Lucene.
[10] El formato de archivo de índice de Lucene actualmente soportado es la versión 2.3 (a partir de Zend Framework 1.6).