19
Indizacin y Bœsqueda a travØs de Lucene Juan Pablo Ramos Hernández 1 , Giner Alor Hernández 2 1 Facultad de Informática, Universidad Autónoma de Sinaloa, prolongación Josefa Ortiz de Domínguez Ciudad Universitaria, Culiacán, Sinaloa. 2 División de Estudios de Posgrado e Investigación, Instituto Tecnológico de Orizaba, Avenida Oriente 9 No. 852 Col. Emiliano Zapata C. P. 94320, Orizaba, Veracruz. E-mail: [email protected], [email protected] Resumen: Lucene es una tecnología para la Recuperación de Información que realiza procesos de indización y búsqueda, cuenta con una API escrita en Java, también está disponible en otros lenguajes de programación, soporta la indización de documentos con formatos: txt, pdf, doc, ppt, rtf, xml y html, la finalidad de este reporte técnico es darle a conocer al lector el uso de esta tecnología, se muestra la introducción e historia, características de Lucene, ejemplos y uso de las principales clases, estructura de un índice, comparación con otras tecnologías y como resultado final la construcción de un motor de búsqueda utilizando Lucene. Palabras clave: Lucene, Recuperacin de Informacin, Indizacin. 1 Introduccin Lucene es una novedosa herramienta que permite tanto la indizacin cmo la bœsqueda de documentos. Creada bajo una metodologa orientada a objetos e implementada completamente en Java, no se trata de una aplicacin que se descarga, instala y ejecuta sino de una API flexible, a travØs de la cual se aæaden, con esfuerzos de programacin, capacidades de indizacin y bœsqueda a cualquier sistema que se estØ desarrollando. [1] Existen otras herramientas, aparte de Lucene, que permiten realizar la indizacin y bœsqueda de documentos pero dichas herramientas se utilizan para usos concretos, lo que implica que el intentar adaptarlas a un proyecto especfico sea una tarea realmente difcil. La idea que engloba Lucene es completamente diferente, ya que su principal ventaja es su flexibilidad, permite su utilizacin en cualquier sistema que lleve a cabo procesos de indizacin o bœsqueda. [1] Lucene tiene versiones para otros lenguajes como Perl, C#, Ruby y C++. Para entrar mÆs a detalle en el siguiente apartado se tratan los orgenes de Lucene. 2 Historia de Lucene El desarrollo y crecimiento masivo de las redes de computadoras y medios de almacenamiento a lo largo de los œltimos aæos, motiva la aparicin de un creciente interØs por los sistemas de clasificacin automÆtica de documentos. [1] Esta necesidad de bœsqueda de datos en la web o en cualquier archivo que contenga texto dio origen a Lucene, para implementarse en cualquier aplicacin o sistema que

3013167 indizacion-y-busqueda-a-traves-de-lucene

Embed Size (px)

Citation preview

Page 1: 3013167 indizacion-y-busqueda-a-traves-de-lucene

Indización y Búsqueda a través de Lucene

Juan Pablo Ramos Hernández1, Giner Alor Hernández2

1Facultad de Informática, Universidad Autónoma de Sinaloa, prolongación Josefa Ortiz de

Domínguez Ciudad Universitaria, Culiacán, Sinaloa. 2 División de Estudios de Posgrado e Investigación, Instituto Tecnológico de Orizaba, Avenida Oriente 9 No. 852 Col. Emiliano Zapata C. P. 94320, Orizaba, Veracruz.

E-mail: [email protected], [email protected]

Resumen: Lucene es una tecnología para la Recuperación de Información que realiza procesos de indización y búsqueda, cuenta con una API escrita en Java, también está disponible en otros lenguajes de programación, soporta la indización de documentos con formatos: txt, pdf, doc, ppt, rtf, xml y html, la finalidad de este reporte técnico es darle a conocer al lector el uso de esta tecnología, se muestra la introducción e historia, características de Lucene, ejemplos y uso de las principales clases, estructura de un índice, comparación con otras tecnologías y como resultado final la construcción de un motor de búsqueda utilizando Lucene.

Palabras clave: Lucene, Recuperación de Información, Indización.

1 Introducción Lucene es una novedosa herramienta que permite tanto la indización cómo la búsqueda de documentos. Creada bajo una metodología orientada a objetos e implementada completamente en Java, no se trata de una aplicación que se descarga, instala y ejecuta sino de una API flexible, a través de la cual se añaden, con esfuerzos de programación, capacidades de indización y búsqueda a cualquier sistema que se esté desarrollando. [1] Existen otras herramientas, aparte de Lucene, que permiten realizar la indización y búsqueda de documentos pero dichas herramientas se utilizan para usos concretos, lo que implica que el intentar adaptarlas a un proyecto específico sea una tarea realmente difícil. La idea que engloba Lucene es completamente diferente, ya que su principal ventaja es su flexibilidad, permite su utilización en cualquier sistema que lleve a cabo procesos de indización o búsqueda. [1] Lucene tiene versiones para otros lenguajes como Perl, C#, Ruby y C++. Para entrar más a detalle en el siguiente apartado se tratan los orígenes de Lucene. 2 Historia de Lucene El desarrollo y crecimiento masivo de las redes de computadoras y medios de almacenamiento a lo largo de los últimos años, motiva la aparición de un creciente interés por los sistemas de clasificación automática de documentos. [1] Esta necesidad de búsqueda de datos en la web o en cualquier archivo que contenga texto dio origen a Lucene, para implementarse en cualquier aplicación o sistema que

Page 2: 3013167 indizacion-y-busqueda-a-traves-de-lucene

requiera un motor de búsqueda, en la figura 1 se muestra como una aplicación hace uso de Lucene. Estos sistemas realizan diferentes operaciones de clasificación basándose en el análisis del contenido del texto de los documentos que procesan. La mayoría de las técnicas de análisis y representación de documentos utilizadas en la actualidad en los sistemas de clasificación, se basan en criterios fundamentalmente estadísticos, centrados en frecuencias de aparición de términos en los documentos. [1]

Figura 1: Lucene primero que nada indiza los documentos o BD que contiene la aplicación

para que después a través de una consulta del usuario, Lucene busque en el índice y muestre los resultados con éxito.

El creador de Lucene, Doug Cutting, tiene la experiencia teórica y práctica significativa en el campo de Recuperación de Información (IR). Cutting preocupado por el decrecimiento de los motores de búsqueda en la web, creó Nutch, una aplicación basada en Lucene, para manejar los índices y buscar en millones de páginas web actualizadas. [2] Después de analizar los orígenes de Lucene se pasa a ver las características (ventajas o desventajas) de esta tecnología.

Page 3: 3013167 indizacion-y-busqueda-a-traves-de-lucene

3 Características de Lucene A continuación se detallan algunas características que hacen de Lucene una herramienta flexible y adaptable: ! Lucene es un API de desarrollo para indización y búsquedas, escrita en Java. ! Está disponible en C++, Perl, C# y Ruby. ! Multiplataforma. ! Permite indización incremental. ! Algoritmos de búsquedas fiables y confiables. ! Permite ordenar resultados por relevancia. ! Lenguaje de consulta. ! Stemming ! Búsqueda por campos, rangos de fecha, entre otras. ! Ordenación por cualquier campo. ! Permite búsqueda mientras se actualiza el índice. ! Lucene soporta la indización de documentos con formato: TXT, PDF, DOC,

RTF, XML,PPT y HTML. [3] Lucene tiene muchas ventajas en cuanto a otras bibliotecas de funciones de IR. En el siguiente apartado se definen indización y búsqueda así como las principales clases que Lucene utiliza para lograr con sus objetivos. 4 Funcionalidad Básica de Lucene 4.1 Indización y Búsqueda En este apartado, y puesto que indización y búsqueda son dos objetivos muy generales, que abarcan multitud de aspectos, se definen y se detallan cada una de ellos. 4.1.1 Concepto de indización Cuando se requiere hacer uso de búsquedas dentro de una aplicación, rápido se viene a la mente crear un programa que haga esto, es decir, que busque en todos los archivos palabras o frases relacionadas, esto tendría fallas en el caso de archivos muy grandes. Por eso es importante crear los índices, transformar el texto en un formato donde la búsqueda sea más rápida, eliminando el proceso de exploración lento. Este proceso de conversión es llamado indización y al archivo resultante se le llama índice. Un índice separa las palabras el documento en campos y permite el acceso rápido a los datos que fueron almacenados en el proceso de indizado. [2] 4.1.2 Concepto de búsqueda La búsqueda es el proceso de entrar al índice y buscar palabras relacionadas, para encontrar documentos donde aparezca. Es importante para la búsqueda tomar en cuenta dos factores: la destitución y la precisión.

Page 4: 3013167 indizacion-y-busqueda-a-traves-de-lucene

La destitución se encarga de indicar que documentos son relevantes a la búsqueda mientras que la precisión se encarga del filtrado de los datos. [2] 4.2 Clases básicas en la indización Las clases que se muestran a continuación son las principales durante el proceso de indización, para ello se definen cada una de ellas y el uso que tienen en Lucene. [2] ! IndexWriter ! Directory ! Analyzer ! Document ! Field

4.2.1 IndexWriter Es el componente central del proceso de indización. Esta clase crea índices y agrega documentos a uno ya existente. IndexWriter es un objeto que permite acceder al índice pero no leer o buscar en el. 4.2.2 Directory La clase Directory representa la ubicación de un índice en Lucene. Esta a su vez utiliza subclases FSDirectory para guardar los índices en el sistema de archivos. Esta es la clase que más se usa para el almacenamiento de índices. La clase IndexWriter hace uso de FSDirectory cuando necesita recibir como parámetro el directorio donde se almacenarán los índices. Otra subclase llamada RAMDirectory, a diferencia de FSDirectory, esta se usa para almacenar los índices en memoria es recomendable cuando se crean índices pequeños o si se realizan pruebas de indización o búsqueda. [2] 4.2.3 Analyzer Antes de indizar un documento este pasa por la clase Analyzer. Esta clase elimina del documento palabras que no ayudan o distinguen un documento de otro como él, la, en, una, entre otras. También convierte en las palabras a minúsculas para que las búsquedas sean más exactas. 4.2.4 Document Una clase Document representa una colección de campos. El documento a indizar es separado en campos o en metadatos como son el titulo del documento, fecha de modificación, autor, entre otras. Estos se guardan en archivos diferentes cuando se indizan. Cuando se hace referencia a un documento se refiere a todo archivo que contenga texto como HTML, PDF, XML, entre otros. [2] 4.2.5 Field

Page 5: 3013167 indizacion-y-busqueda-a-traves-de-lucene

Cada documento contiene uno o más campos, en Lucene existen 4 métodos Field diferentes:

1. Keyword: Se almacena y se indiza tal cual, no se analiza, se utiliza para los campos que necesitan guardarse en el índice sin modificaciones como el número de seguridad social, los sitios de internet, directorio donde se encuentra el documento, entre otras.

2. UnIndexed: Se almacena pero nunca se usa en las búsquedas, como las llaves primarias en una base de datos.

3. Text: el valor se analiza e indiza, el valor original también se almacena. 4. UnStored: Es la opuesta a UnIndexed. Se analiza e indiza, se utiliza para

todos los documentos de texto o sitios web donde solo se requiera guardar titulo y contenido. [2]

4.3 Clases básicas para la búsqueda Para llevar a cabo una búsqueda con Lucene es importante familiarizarse con las siguientes clases: [2] ! IndexSearcher ! Term ! Query ! TermQuery ! Hits

4.3.1 IndexSearcher IndexSearcher es en la búsqueda lo que IndexWriter es en la indización. Es la clase principal que abre el índice para buscar en el, ofrece varios métodos de búsqueda, lo que hace esta clase es pasar como parámetro la query y regresar un objeto hits. 4.3.2 Term Un término es la unidad básica para la búsqueda. Similar al objeto Field, consiste de un par de elementos: el nombre del campo y su valor. Por ejemplo en la siguiente figura 2 se busca la palabra lucene en el contenido del documento. Un ejemplo seria:

Query q = new TermQuery(new Term("contents", "lucene")); Hits hits = is.search(q);

Figura 2: Muestra el uso de una clase Term en Lucene.

4.3.3 Query Lucene tiene diferentes subclases de Query, la más utilizada es TermQuery por los métodos que ella contiene. [2] 4.3.4 TermQuey

Page 6: 3013167 indizacion-y-busqueda-a-traves-de-lucene

Es el tipo de Query mas básico soportada por Lucene, se utiliza para hacer coincidir documentos que tienen valores específicos. 4.3.5 Hits La clase Hits almacena los puntos de referencia a los resultados de la búsqueda, es decir todos los documentos encontrados que se relacionan con la Query. [2] Vistas las clases principales, es importante ver realmente la funcionalidad de esta tecnología por lo cual en el siguiente aparatado se desarrollan ejemplos de cómo usar Lucene con dos importantes objetivos indización y búsqueda. 5 Ejemplos y usos de la las principales clases que proporciona Lucene para los procesos de Indización y Búsqueda En este caso para compilar y ejecutar los siguientes ejemplos, es necesario descargar el archivo .jar de la versión 1.4.3 de Lucene, además de contar con algún IDE (Interfaz de Desarrollo) de Java en este caso se recomienda KawaPro versión 5.0, con el compilador de Java jdk versión 1.4. 5.1 Creación de un índice con Lucene La creación de un índice constituye el punto de partida para el trabajo con Lucene, puesto que una vez que es creado, se irán añadiendo todos aquellos documentos que serán indizados. El sencillo programa que se muestra a continuación en la figura 3, CreateIndice.java, construye un índice vacío, para lo cual simplemente crea un objeto IndexWriter.

package uas; import org.apache.lucene.index.IndexWriter;

import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.*; import java.io.*; import java.util.Date; public class CreateIndice { public static void main(String[] args) throws Exception { File indexDir = new File(("c:\\indexdir"); IndexWriter writer; writer = new IndexWriter(indexDir, null, true); writer.close(); }

}

Figura 3: Muestra la creación de un índice en Lucene. La clase IndexWriter se utiliza tanto para la creación de índices como para su mantenimiento. Cuando se crea un objeto de esta clase, como se observa en el ejemplo, al constructor se le pasan tres parámetros. De los cuales, solamente son relevantes el primero y el tercero: el primero representa el path (directorio) dónde se almacena el índice y con el valor del tercero establecido

Page 7: 3013167 indizacion-y-busqueda-a-traves-de-lucene

a true, indicamos que lo que estamos es creando el índice y no abriéndolo para su mantenimiento. El segundo de los parámetros se establece a un valor null. El método close() se llama para liberar todos los recursos asociados a la creación del índice. 5.2 Añadir documentos a un índice Una vez que se crea el índice, está listo para empezar a añadirle documentos. El siguiente programa Indexer.java en la figura 4, indiza archivos con formato .txt, se puede cambiar la extensión a .doc, .html, ppt, .xml, .rtf y funciona igual.

package uas; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.*; import java.io.*; import java.util.Date; public class Indexer { public static void main(String[] args) throws Exception { File indexDir = new File("c:\\indexdir"); File dataDir = new File("c:\\datadir"); long start = new Date().getTime(); int numIndexed = index(indexDir, dataDir); long end = new Date().getTime(); System.out.println("Se han indizado " + numIndexed + " archivos

en " + (end - start) + " milisegundos"); } public static int index(File indexDir, File dataDir) throws IOException { if (!dataDir.exists() || !dataDir.isDirectory()) { throw new IOException(dataDir + " no existe o no es un directorio "); } IndexWriter writer = new IndexWriter(indexDir, new

StandardAnalyzer(), true); writer.setUseCompoundFile(false); indexDirectory(writer, dataDir); int numIndexed = writer.docCount(); writer.optimize(); writer.close(); return numIndexed; } private static void indexDirectory(IndexWriter writer, File dir) throws IOException { File[] files = dir.listFiles(); for (int i = 0; i < files.length; i++) { File f = files[i]; if (f.isDirectory()) { indexDirectory(writer, f); // recurse } else if (f.getName().endsWith(".txt")) { indexFile(writer, f); } } } private static void indexFile(IndexWriter writer, File f) throws IOException {

Page 8: 3013167 indizacion-y-busqueda-a-traves-de-lucene

if (f.isHidden() || !f.exists() || !f.canRead()) { return; } System.out.println("Indizando " + f.getCanonicalPath()); Document doc = new Document(); doc.add(Field.Text("contents", new FileReader(f))); doc.add(Field.Keyword("filename", f.getCanonicalPath())); writer.addDocument(doc); }

}

Figura 4: Ejemplo que muestra como se indizan los archivos de texto con Lucene. Para cada uno de los documentos, se crea un objeto Document y posteriormente se llama al método addDocument del IndexWriter para añadirlo al índice. Cuando creamos un objeto Document, la llamada al constructor, como se observa en el ejemplo, no requiere ningún parámetro y construye un nuevo documento sin ningún campo. Una vez creado el documento, para añadirle campos, se utiliza el método add, al que pasamos el campo como parámetro. A la hora de crear un objeto Field, se toman en cuenta importantes consideraciones, ya que algunas de las decisiones que se tomen en este punto afectarán en los posteriores procesos de búsqueda sobre el índice. En el caso del contenido del documento se utiliza el método Text para indicar que el valor se analiza e indiza, el valor original también se almacena. Finalmente para el nombre del archivo se utiliza el método Keyword para indicar que se almacene y se indize tal cual, no se analiza. Una vez construido el documento con los campos deseados, éste se añade al índice a través del método addDocument de IndexWriter. Cuando se abre un índice para añadir documentos, al constructor de IndexWriter se le pasa como parámetro el nombre de dicho índice, un objeto Analizer, y un valor booleano establecido a false, para indicar que no se crea un índice sino que se abre uno ya existente. Un objeto Analyzer se crea para analizar un texto y en base a un determinado criterio, obtener la representación interna de dicho texto en el índice. Los Analizadores preprocesan el texto de entrada convirtiendo éste en una secuencia de �tokens� (trozos de texto) y se utilizan tanto al añadir un documento a un índice como en los procesos de búsqueda, puesto que el texto o criterio de búsqueda se procesa de la misma manera que el contenido de los campos del documento cuando éste se añade al índice. Uno de los criterios de análisis más utilizados es el de la lista de parada, que consiste en eliminar del texto una serie de palabras que no resultan útiles para la obtención de términos tanto de indización como de búsqueda, como por ejemplo, de, en, el, entre otras. En este caso, el objeto que se pasa al constructor de IndexWriter, es un objeto StopAnalyzer, subclase de Analyzer. Cualquier aplicación que haga uso de Lucene proporciona los datos que se indizaran bien como un String o bien como InputStream. Es por esta razón que Lucene permite la indización de datos, no sólo de archivos, sino de cualquier fuente (Base de Datos, entre otras.). En el caso que los documentos se encuentren almacenados en archivos, se utiliza FileInputStream para recuperarlos; si se encuentran en una base de datos, se hace uso

Page 9: 3013167 indizacion-y-busqueda-a-traves-de-lucene

de InputStream y de manera similar, se recupera contenido HTML, por ejemplo, utilizando FilterInputStream, que permite la eliminación de etiquetas. 5.3 Búsqueda de documentos de texto La búsqueda de documentos constituye la funcionalidad principal proporcionada por Lucene. Para ello aporta múltiples clases y métodos para la representación de consultas y buscar en el índice aquellos documentos que son relevantes y cumplen con los criterios de la búsqueda. El programa que se muestra a continuación, Searcher.java en la figura 5, es un ejemplo de cómo buscar en un índice utilizando Lucene.

package uas; import org.apache.lucene.document.Document; import org.apache.lucene.search.*; import org.apache.lucene.store.*; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.analysis.standard.StandardAnalyzer; import java.io.File; import java.util.Date; public class Searcher { public static void main(String[] args) throws Exception { String[] argsv=new String[2]; argsv[0]=new String("c:\\indexdir"); argsv[1]=new String("lucene"); File indexDir = new File(argsv[0]); String q = argsv[1]; if (!indexDir.exists() || !indexDir.isDirectory()) { throw new Exception(indexDir + " no existe o no es un

directorio. "); } search(indexDir, q); } public static void search(File indexDir, String q) throws Exception { Directory fsDir = FSDirectory.getDirectory(indexDir, false); IndexSearcher is = new IndexSearcher(fsDir); Query query = QueryParser.parse(q, "contents", new StandardAnalyzer()); long start = new Date().getTime(); Hits hits = is.search(query); long end = new Date().getTime(); System.out.println ("Se han encontrado " + hits.length() + " documento(s) (en " + (end - start) + " millisegundos) relacionados con la palabra '" + q + "' en los directorios: "); for (int i = 0; i < hits.length(); i++) { Document doc = hits.doc(i); System.out.println(doc.get("filename")); } } }

Figura 5: Muestra el código para la búsqueda de documentos con Lucene.

Page 10: 3013167 indizacion-y-busqueda-a-traves-de-lucene

Las tres clases más importantes que proporcionan métodos relacionados con la búsqueda de documentos indizados son Search, Hits y Query (con sus respectivas subclases). La clase Searcher es una clase abstracta y constituye la base para cualquier búsqueda en un índice de documentos. Declara métodos que se implementan por sus subclases, como por ejemplo, IndexSearcher, proporcionando así la forma de acceder y recuperar información indizada. En el caso de Searcher.java, se crea un objeto de este tipo, pasando al constructor un único parámetro, el directorio dónde se encuentra el índice de documentos. El método más importante de esta clase es el método search(), que devuelve todos aquellos documentos que cumplen con las condiciones de la búsqueda. En la cual se corrobora que junto con Searcher, a la hora de realizar búsquedas de documentos en un índice destacan Hits y Query. La clase Query, al igual que Searcher es una clase abstracta siendo QueryParser su subclase más importante, de la cual el método que más funcionalidad proporciona a la búsqueda de documentos es parse(). Este método partiendo de una cadena de entrada, del campo del documento dónde se realiza la búsqueda y de un analizador, obtiene como parámetro de salida una Query. Una vez que se obtiene una Query, pasada como argumento al método search(), ésta devuelve un objeto Hits, que representa una colección ordenada de documentos. El orden se determina por la relevancia de cada documento en la búsqueda implementada por la Query. De esta manera se obtienen aquellos documentos que cumplen con las expectativas de la búsqueda, en la figura 6 se muestra el uso de las clases principales que utiliza Lucene, del lado izquierdo y con línea punteada se muestra el proceso de indización; los documentos pasan por el analizador de Lucene, se utiliza la clase IndexWriter para la creación del índice, por otro lado se aprecia la búsqueda, el usuario proporciona la Query, y el analizador de Lucene se encarga de buscar coincidencias o relevancias en los documentos, mandando como resultado final los Hits, es decir, los documentos que contienen la palabra proporcionada por el usuario.

Figura 6: Proceso de indización y búsqueda con Lucene.

Page 11: 3013167 indizacion-y-busqueda-a-traves-de-lucene

Visto el uso de las clases principales de Lucene se pasa ahora a ver la estructura o los archivos que Lucene crea para posteriormente realizar las búsquedas. 6. Estructura de un índice En los ejemplos, si se checa el directorio del índice creado, se ve que hay varios archivos que al principio parecen similares. Estos son los archivos del índice en la figura 7 y tienen la siguiente estructura:

Deletetable _1fyc.f1 _1fyc.f2 _1fyc.fdt _1fyc.fdx _1fyc.fnm _1fyc.frq _1fyc.prx _1fyc.tii _1fyc.tis Segments

Figura 7: Muestra los archivos que se generan en la creación de un índice con Lucene, este

tipo de archivo se crea cuando se optimiza el índice.

Un índice se forma por segmentos, documentos, campos y términos. Cada índice contiene uno o más segmentos. Un segmento se forma por uno o más documentos. Cada documento tiene uno o más campos y cada campo se forma por uno o más términos. Cada término es un par de secuencias que representan un nombre de campo y un valor. Un segmento consiste en una serie de archivos. El número exacto de los archivos que constituyen cada segmento varía de índice a índice, y depende del número de los campos que el índice contiene. Todos los archivos que pertenecen al mismo segmento comparten un prefijo común y diferencian en el sufijo. Se observa que todos los archivos que pertenecen a este segmento comienza con un prefijo común: _lfyc. Este índice contiene dos campos, hay dos archivos con el sufijo del fN, donde N es un número. Si este índice tuviera tres campos, un archivo nombrado _ lfyc.f3 también estaría presente en el directorio del índice. El número de segmentos en un índice es fijo una vez que el índice se construya completamente, pero varía mientras que la indización de direcciones está en marcha. Lucene agrega segmentos como los nuevos documentos se agregan al índice, y combina los segmentos a menudo. [4] 6.1 Optimizar un índice Para optimizar un índice, uno tiene que llamar el método optimize() de la clase IndexWriter. Cuando esto sucede, todos los documentos en memoria pasan al disco duro y todos los segmentos del índice se combinan en un solo segmento, reduciendo el número de archivos que se crean para el índice. [5]

Page 12: 3013167 indizacion-y-busqueda-a-traves-de-lucene

Sin embargo, la optimización de un índice no ayuda a mejorar funcionamiento de la indización de direcciones. De hecho, la optimización de un índice durante el proceso de la indización de direcciones retardará solamente las cosas. A pesar de esto, la optimización puede a veces ser necesaria para guardar el número de archivos abiertos bajo control. Por ejemplo, la optimización de un índice durante el proceso de la indización de direcciones se puede necesitar en las situaciones donde buscar e indizar son concurrentes, puesto que ambos procesos guardan su propio sistema de archivos abiertos. Una buena regla es que si más documentos se agregan pronto al índice, se debe evitar llamar el método optimize(). Por otra parte, si el índice no será modificado por buen tiempo, y el índice se usa para la búsqueda solamente, se debe optimizar. Eso reducirá el número de los segmentos (archivos en el disco duro), y por lo tanto mejora funcionamiento de la búsqueda, entre menos sea el número de archivos que Lucene tiene que abrir mientras se busca, más rápida es la búsqueda. En la siguiente figura 8 se muestra el contenido de los archivos del índice. [5]

Figura 8: Esta imagen muestra el contenido de los archivos creados por el índice, el archivo .fnm almacena los campos de los documentos, el archivo .tii contiene información acerca de

esos campos, es decir, nombre del campo y valor, el archivo .prq almacena el numero de documento y la frecuencia de aparición, mientras que el archivo .prx contiene la posición donde

se encuentra. Después de analizar la estructura de un índice y lo que almacena cada uno de sus archivos; es importante también conocer otras tecnologías de recuperación de

Page 13: 3013167 indizacion-y-busqueda-a-traves-de-lucene

información, en la siguiente sección se hace una comparativa de Lucene con otras bibliotecas de funciones importantes. 7 Estudio o análisis comparativo de Lucene con otras tecnologías de Recuperación de Información. 7.1 Lemur Como sistema de Recuperación de Información, Lemur permite todas las etapas desde la indización a la búsqueda de documentos. Lemur aporta una poderosa API implementada en C++ y está diseñada para trabajar en todos los sistemas operativos, permite la indización incremental e indiza atributos de los documentos. [6] 7.2 Xapian Xapian es una biblioteca de funciones OpenSource de Recuperación de Información, para crear motores de búsqueda está escrita en C++, pero también se encuentra disponible en otros lenguajes como Perl, Python, PHP, Java, C#, and Ruby. Xapian contiene una API potente y adaptable que le facilita al programador los procesos de indización y búsqueda. [7] 7.3 Terrier Terrier esta implementado en Java, facilita mucho el trabajo a los programadores ya que permite indizar una colección de documentos de forma que se sabe cuántos documentos contienen un término determinado, permite la búsqueda. 7.4 Comparación de Lucene con Lémur, Terrier y Xapian ! Lucene es multiplataforma, al igual que Lemur, las demás tecnologías no. ! Terrier y Lucene son implementados en Java, Lemur y Xapian en C++,

aunque todas tienen soporte para otros lenguajes de programación. ! Todas indizan diferentes formatos de texto como: PDF, WORD, HTML,

HTM, TXT, XML, RTF, entre otras. ! Lucene permite Stemming para varios idiomas, las demás tecnologías

también. ! Lucene permite búsqueda mientras se actualiza el índice, lo que otras

tecnologías no hacen. ! Lemur y Lucene permiten la indización incremental, Xapian y Terrier no. ! Todas trabajan con modelos probabilísticos, excepto Lucene que trabaja con

el modelo de espacio vectorial. ! Todas las tecnologías son OpenSource (Software Libre). ! Lucene permite búsqueda por cualquier campo, las demás tecnologías no.

Cabe mencionar que es de suma importancia conocer que existen otras tecnologías aparte de Lucene por eso en este apartado se muestran las ventajas que una u otra pueden tener. También es importante conocer que ambientes de desarrollo abarcan a

Page 14: 3013167 indizacion-y-busqueda-a-traves-de-lucene

Lucene además de Java existen otros lenguajes donde se implementa los cuales se explican en la siguiente sección. 8 Implementación de Lucene en otros lenguajes de programación. 8.1 cLucene La API de cLucene es similar a Lucene. Esto significa que el código escrito en Java se convierte fácilmente al lenguaje de programación C++. La desventaja es que cLucene no sigue el código estándar de C++. Sin embargo, debido al número de clases que se tienen que rediseñar, cLucene sigue el código estándar de Java. Esto también permite que mucho del código sea convertido usando macros y scripts. [2] 8.2 dotLucene Está escrito en C#, dotLucene tiene una API que es casi idéntica a la de Lucene. Por lo tanto, el código escrito en Lucene puede ser trasladado fácilmente a C#. Esta compatibilidad también permite que los desarrolladores de .NET utilicen la documentación para la versión de Java. Mientras que en Java los nombres de los métodos comienzan con letras minúsculas, en la versión de .Net los nombres de los métodos comienzan con mayúscula. [2] 8.3 pLucene Es una herramienta directa de Lucene y reserva una API extensa. La única diferencia obvia está en el estilo del código, el cual sigue el estándar para el manejo y estructura de módulos, métodos y clases de Perl. Aunque el API de pLucene se asemeja a la de Lucene, existen algunas diferencias, según los desarrolladores de pLucene, Java utiliza enteros largos de 64 bits pero la mayoría de las versiones de Perl utilizan 32 bits. [2] 8.4 Lupy La sintaxis de Phyton se hace a un lado, la API de Lupy se asemeja a Lucene. Cuando se indizan documentos las clases y los métodos son muy familiares. Sin embargo, podemos crear un IndexWriter sin especificar analizador es, algo que no podemos hacer en Lucene. [2] En este reporte técnico se explica de manera detallada una tecnología reciente, que nos permite de una manera fácil implementar motores de búsqueda a las aplicaciones, por lo cual en la siguiente sección se muestra un ejemplo de ello.

Page 15: 3013167 indizacion-y-busqueda-a-traves-de-lucene

9 Ejemplo de un motor de búsqueda utilizando Lucene.

Un motor de búsqueda es un sistema informático que indiza archivos, páginas web y base de datos. Cuando se requiere información sobre algún tema es necesario proporcionarle la palabra o tema a buscar, el resultado de la búsqueda son enlaces relacionados al documento que contiene dicha palabra. El siguiente ejemplo de motor de búsqueda, lucene.war utiliza los programas createindice.java, indexer.java, searcher.java y el archivo .jar de la versión de Lucene 1.4.3, principales para llevar a cabo la indización y búsqueda vistas en la sección de funcionalidad básica de Lucene de este reporte técnico, el servidor que se utiliza es Apache Tomcat versión 5.0.30, juntos con los archivos .jsp que conforman la aplicación. En la siguiente figura 9 se aprecia la página principal de un motor de búsqueda basado en Lucene que indiza diferentes formatos de texto y realiza búsqueda de palabras en el sistema de archivos.

Figura 9: Muestra la página de inicio de la aplicación, del lado izquierdo se encuentra el

proceso de indización de documentos y del lado derecho la búsqueda. Para empezar a trabajar con esta aplicación web es necesario crear un índice para así irle agregando los documentos indizados los cuales se les van a realizar las búsquedas posteriores, en la siguiente figura 10 del lado izquierdo, crearemos el índice, esto es necesario cuando vas a empezar a trabajar con la aplicación o también cuando quieres borrar un índice anterior para crear un nuevo, asi se crean los segmentos, cuando ocurra algún problema en el servidor solo hay que detenerlo ir al directorio donde están los índices y borrarlos manualmente se vuelve a iniciar el servidor apache tomcat y se crea el índice, el directorio que guarda los índices se encuentra establecido por defecto en c:/indexdir, si se desea cambiar la ruta es necesario modificar el archivo procesa.jsp.

Page 16: 3013167 indizacion-y-busqueda-a-traves-de-lucene

Figura 10: Se muestra el resultado de la creación de un índice.

En la siguiente figura 11 se debe indicar en qué directorio se encuentran los documentos a indizar y qué tipo de archivo quiere indizar, para que Lucene se encargue de lo demás.

Figura 11: Proceso de indización con Lucene.

El resultado del proceso de indización se muestra en la siguiente figura 12, muestra el número de documentos que fueron indizados y el tiempo que se tardo en hacerlo, es importante tomar en cuenta que el proceso de indización no se hará muy a menudo, solo cuando se agregan nuevos documentos al directorio.

Page 17: 3013167 indizacion-y-busqueda-a-traves-de-lucene

Figura 12: Muestra el resultado del proceso de indización, indicando cuantos documentos fueron indizados y el tiempo en que se tardó en hacerlo.

La búsqueda con Lucene es de suma importancia en la siguiente figura 13, es necesario proporcionar la palabra clave para encontrar el documento deseado.

Figura 13: Muestra la búsqueda con Lucene el usuario proporciona la palabra(s), Lucene se encarga de encontrar documentos relacionados a esa palabra.

Después de indicar en el motor de búsqueda la palabra clave aparecen los resultados mostrando los directorios donde se encuentran los documentos como se muestra en la figura 14.

Page 18: 3013167 indizacion-y-busqueda-a-traves-de-lucene

Figura 14: Muestra los resultados de la búsqueda con Lucene.

Page 19: 3013167 indizacion-y-busqueda-a-traves-de-lucene

10 Conclusiones Lucene es una tecnología de indización y búsqueda que se utiliza en muchos motores de búsqueda principalmente en Google, es recomendable empezar a conocer esta herramienta ya que el proceso de indización es preciso y la búsqueda de documentos es muy exacta. Es posible utilizarla en varios lenguajes de programación no solo en Java lo que permite que diversos programadores les llame la atención, cuenta con algoritmos de búsquedas confiables e indiza cualquier formato de texto y además es multiplataforma. Ofrece muchas ventajas en cuanto a otras tecnologías, sobre todo en tiempo de indización y búsqueda ya muestra resultados muy rápido. 11 Agradecimientos Agradezco a la Academia Mexicana de Ciencias por darme la oportunidad y por aceptarme como participante del Verano de Investigación Científica 2007. A la Universidad Autónoma de Sinaloa, en especial a la Facultad de Informática Culiacán por todo el apoyo social y económico brindado. Al Instituto Tecnológico de Orizaba por abrirnos las puertas y permitirnos la estancia en especial a mi asesor el Dr. Giner Alor Hernández por dedicar el tiempo y espacio necesario ya que sin su ayuda no hubiera sido posible la realización de este Reporte Técnico, agradezco también a todos mis familiares y amigos que me apoyaron económicamente a todos GRACIAS. 12 Bibliografía [1] Motor de búsqueda para un SRI con agrupamiento, http://trevinca.ei.uvigo.es/~pcuesta/sm/practicas/Lucene.pdf, 28/Junio/2007. [2] Otis Gospodnetic et.al., "Lucene in action", Manning, 2005, pp. 44, 45, 46,53, 54, 55, 56, 57, 58, 59, 349, 352, 353, 355. [3] Indexación con Lucene, http://www.sia.eui.upm.es/isa/lib/exe/fetch.php?id=asignaturas%3Aagentes_inteligentes&cache=cache&media=asignaturas:licencias.pdf, 27/Junio/2007. [4] Advanced Text Indexing with Lucene, http://www.onjava.com/pub/a/onjava/2003/03/05/lucene.html, 15/Julio/2007. [5] Advanced Text Indexing with Lucene, http://www.onjava.com/pub/a/onjava/2003/03/05/lucene.html?page=2, 15/Julio/2007. [6] The Lemur Toolkit Features, http://www.lemurproject.org/features.php, 11/Agosto/2007. [7] Features, http://www.xapian.org/features.php, 11/Julio/2007. [8] Terrier: TERabyte RetrIEveR (I), http://www.ojobuscador.com/2006/08/04/terrier-terabyte-retriever-i/, 3/Agosto/2007.