You are on page 1of 19

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

1 2
Juan Pablo Ramos Hernández , Giner Alor Hernández
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: jpramoshernandez@gmail.com, galor@itorizaba.edu.mx

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
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.
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.
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
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
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
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 {
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
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.
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.
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]
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
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
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.
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.
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.
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.
Figura 14: Muestra los resultados de la búsqueda con 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_inteligent
es&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.