Está en la página 1de 11

UPC

Conocimiento en Lnea
Lucene: Tutorial
Version 0.2

Conocimiento en Lnea
Lucene: Tutorial
Conocimiento-en-Linea - Lucene: Tutorial

Version:
0.2
Date: 06/03/2009

Revision Histrica
Date
06/03/2009

Confidencial

Version
0.2

Description
Creacin del documento. Incluye:
Introduccin, Informacin general y
operaciones bsicas con el IndexWriter
e IndexSearcher.

UPC, 2015

Author
Ivn Alonso Fernndez Cavero

Page 2 of 11

Conocimiento en Lnea
Lucene: Tutorial
Conocimiento-en-Linea - Lucene: Tutorial

Version:
0.2
Date: 06/03/2009

ndice
1.

Introduccin
1.1
Propsito
1.2
Alcance
1.3
Definiciones, Acrnimos, and Abreviaciones
1.4
Resumen

2.

Informacin General
2.1
Vista de Lucene
2.2
Descarga
2.3
Documentacin e Informacin

3.

Operaciones con el IndexWriter


3.1
Inicializar el IndexWriter
3.2
Clase Analyzer
3.3
Document Class y Field Class
3.4
Escribir en el ndice
3.5
Borra un documento del ndice

4.

Operaciones con el IndexSearcher


4.1
Clase QueryParser y clase Query
4.2
Realizar la busqueda con TopDocCollector
4.3
Realizar la busqueda con HitCollector
4.4
Dar formato a los resultados

5.

Parsers

Confidencial

UPC, 2015

Page 3 of 11

Conocimiento en Lnea
Lucene: Tutorial
Conocimiento-en-Linea - Lucene: Tutorial

Version:
0.2
Date: 06/03/2009

Lucene: Tutorial
1.

Introduccin
Lucene es un motor de bsqueda de alto rendimiento escrito en Java y es Open Source. Es escalable y logra
su alto rendimiento mediante el uso de ndices. Tiene algoritmos de bsqueda eficientes. Estos algoritmos
permiten rankear los resultados (haciendo posible obtener primero los mejores resultados); hacer phrase
queries, wildcard queries, proximity queries, range queries y ms; bsquedas por campos; ordenar por
cualquier campo; y bsquedas a mltiples ndices unindolos.

1.1

Propsito
El propsito de este documento es documentar todos los conocimientos obtenidos con Lucene durante el
desarrollo del Proyecto Conocimiento en Lnea.

1.2

Alcance
El presente documento tiene como alcance explicar solo las funcionalidades utilizadas con Lucene para el
desarrollo del Proyecto Conocimiento en Lnea.

1.3

Definiciones, Acrnimos, and Abreviaciones


ndice: El ndice de una base de datos es una estructura de datos que mejora la velocidad de las
operaciones, permitiendo un rpido acceso a los registros de una tabla. Al aumentar drsticamente la
velocidad de acceso, se suelen usar sobre aquellos campos sobre los cuales se hagan frecuentes bsquedas.
Campo o Field = Columna de una tabla.
Query = Consulta.

1.4

Resumen
Primero se dar a conocer una vista general de Lucene y su arquitectura. Luego se explicara las operaciones
de indexamiento y bsqueda mediante el uso del IndexWriter e IndexSearcher. Finalmente, se explicara el
uso de los parsers.

2.

Informacin General

2.1

Vista de Lucene

Nota: los parsers no son parte de Lucene. Uno mismo debe convertir los documentos a texto.
Confidencial

UPC, 2015

Page 4 of 11

Conocimiento en Lnea
Lucene: Tutorial
Conocimiento-en-Linea - Lucene: Tutorial

Version:
0.2
Date: 06/03/2009

Vista lgica del ndice

Flujo de una bsqueda

2.2

Descarga
Puede descargar la ltima versin de Lucene aqu: http://www.apache.org/dyn/closer.cgi/lucene/java/

2.3

Documentacin e Informacin
Documentacin: http://lucene.apache.org/java/2_4_0/gettingstarted.html
JavaDocs: http://lucene.apache.org/java/2_4_0/api/index.html
Wiki: http://wiki.apache.org/lucene-java

Confidencial

UPC, 2015

Page 5 of 11

Conocimiento en Lnea
Lucene: Tutorial
Conocimiento-en-Linea - Lucene: Tutorial

Version:
0.2
Date: 06/03/2009

3.

Operaciones con el IndexWriter

3.1

Inicializar el IndexWriter
Esta clase permite realizar todas las operaciones que manipula el ndice. Primero se debe crear un objeto de
esta clase pasndole como parmetro la ruta del ndice, el analizador (Explicado en la seccin 3.2) a usar.
Analyzer analyzer = new SpanishAnalyzer();
String indexPath = C://lucene//indexDir
IndexWriter writer = new IndexWriter(indexPath, analyzer);

3.2

Clase Analyzer
Esta clase sirve como filtro cuando se indexa el texto. Por ejemplo, en este proyecto se uso una clase
llamada SpanishAnalyzer que extiende a Analyzer y usa filtros para omitir palabras que no queremos
indexar como estas, como, ir, a, b c, etc. Estas palabras no sirven para realizar una bsqueda.
As mismo, existen otros filtros que se le pueden aadir como omitir caracteres especiales o convertir todo
a minsculas. Lista de analyzers: BrazilianAnalyzer, ChineseAnalyzer, CJKAnalyzer, CzechAnalyzer,
DutchAnalyzer, FrenchAnalyzer, GermanAnalyzer, GreekAnalyzer, KeywordAnalyzer, PatternAnalyzer,
PerFieldAnalyzerWrapper, QueryAutoStopWordAnalyzer, RussianAnalyzer, ShingleAnalyzerWrapper,
SimpleAnalyzer, SnowballAnalyzer, StandardAnalyzer, StopAnalyzer, ThaiAnalyzer y
WhitespaceAnalyzer.

3.3

Document Class y Field Class


Para poder indexar uno debe tener objetos del tipo Document. Estos documentos estn compuestos de
campos llamados Field.
Ejemplo:
private Document createDocument(String fileName, String absolutePath, String user,
String date, String revision, String content) {
Document doc = new Document();
doc.add(new Field("Contenido", content, Field.Store.YES,
Field.Index.TOKENIZED));
doc.add(new Field("Nombre", fileName, Field.Store.YES,
Field.Index.UN_TOKENIZED));
doc.add(new Field("Ruta", absolutePath, Field.Store.YES,
Field.Index.UN_TOKENIZED));
doc.add(new Field("Usuario", user, Field.Store.YES,
Field.Index.UN_TOKENIZED));
doc.add(new Field("Fecha", date, Field.Store.YES,
Field.Index.UN_TOKENIZED));
doc.add(new Field("Revision", revision, Field.Store.YES,
Field.Index.UN_TOKENIZED));
return doc;
}
Este mtodo crea un documento aadiendo campos como Nombre, Ruta, su contenido, el usuario, la fecha

Confidencial

UPC, 2015

Page 6 of 11

Conocimiento en Lnea
Lucene: Tutorial
Conocimiento-en-Linea - Lucene: Tutorial

Version:
0.2
Date: 06/03/2009

y la revisin a la que pertenece el documento. Los parmetros para crear un Field son: El nombre del
campo, el valor del campo, un Field.Store que pregunta si se va a ser almacenado el campo, y finalmente
Field.Index que puede tener los siguientes valores:
ANALYZED: Pasa por el filtro, el analyzer.
NO: no ser indexado el contenido.
NOT_ANALYZED: No pasa por el filtro, el analyzer.
3.4

Escribir en el ndice
Escribir en el ndice es sencillo. Una vez que se a creado el documento se llama al mtodo
addDocument()
Document = createDocument(File.txt, C://lucene//dataDir//File.txt, Tequila_Burp,
06/03/2009, 55, Este es un archive de texto de prueba);
writer.addDocument(doc);
writer.optimize();
writer.close();
Siempre que se termine de usar el InderWriter se optimiza y cierra.

3.5

Borra un documento del ndice


Para borral del ndice solo se necesita esta lnea de comando:
String absolutePath = /Proyecto/lucene/archive.doc
writer.deleteDocuments(new Term("Ruta", absolutePath));
En este ejemplo se borra todos los documentos que sean iguales al absolutePath en el campo Ruta

4.

Operaciones con el IndexSearcher


Esta clase permite hacer todas las operaciones de consultas al ndice. Para construirlo se pasa como
parmetro la ruta en donde se encuentra el ndice.
IndexSearcher searcher = new IndexSearcher(C://lucene//indexDir);

4.1

Clase QueryParser y clase Query


Estas clases permiten construir una consulta. El siguiente ejemplo muestra como se hace una consulta en
donde se desea buscar la palabra Ivan en el campo Nombre.
String field = Nombre;
String SearchField = Ivan;
Analyzer analyzer = new SpanishAnalyzer();
QueryParser parser = new QueryParser(field, analyzer);
Query query = parser.parse(SearchField);

Confidencial

UPC, 2015

Page 7 of 11

Conocimiento en Lnea
Lucene: Tutorial
Conocimiento-en-Linea - Lucene: Tutorial
4.2

Version:
0.2
Date: 06/03/2009

Realizar la busqueda con TopDocCollector


Esta clase permite recolectar los documentos ms relevantes en el ndice segn la consulta. No es
recomendable pasar como parmetro un nmero elevado de resultados, porque puede influir en el rendimiento.
Todo depende de la potencial del servidor o la cantidad necesaria de resultados que se necesite.
int maxhits = 300;
TopDocCollector collector = new TopDocCollector(maxhits);
Ejemplo completo:
public static ScoreDoc[] Search(String SearchField, String field) throws Exception {
ScoreDoc[] scoreDocs = null;
IndexSearcher searcher = null;
try {
ConfigSingleton jp = ConfigSingleton.getInstance();
searcher = new IndexSearcher(jp.getIndexDir());
Analyzer analyzer = SpanishAnalyzer.getInstance();
QueryParser parser = new QueryParser(field, analyzer);
Query query = parser.parse(SearchField);
TopDocCollector collector = new TopDocCollector(Integer.parseInt(jp.getMaxHits()));
searcher.search(query, collector);
scoreDocs = collector.topDocs().scoreDocs;
} catch (Exception e) {
throw e;
}
return scoreDocs;
}
Aqu se extrae todos los punteros que hicieron match con la consulta. ConfigSingleton es una clase que tiene
en memorial as propiedades de la aplicacin.

4.3

Realizar la busqueda con HitCollector


Esta es una clase de bajo nivel. A diferencia del TopDocCollector esta clase no devuelve los documentos
con un nivel de relevancia pero devuelve todos los documentos que hicieron match con la consulta (solo
sus punteros). Se recomienda usar esta clase si se quiere tener todos los resultados, pero solo se recomienda
iterar sobre los resultados necesarios. Mas especifico, no llamar a Searcher.doc(int) or
IndexReader.document(int) sobre cada documento.
final List<Integer> tempHits = new ArrayList<Integer>();
searcher.search(query, new HitCollector() {
@Override
public void collect(int doc, float score) {
tempHits.add(doc);
}
});

Confidencial

UPC, 2015

Page 8 of 11

Conocimiento en Lnea
Lucene: Tutorial
Conocimiento-en-Linea - Lucene: Tutorial

Version:
0.2
Date: 06/03/2009

Ejemplo completo:
public static Object[] getIndex() throws Exception {
String rangeDate = "[20000101000000 TO 20900101000000]";
IndexSearcher searcher = null;
Object[] docsID = null;
try {
ConfigSingleton jp = ConfigSingleton.getInstance();
searcher = new IndexSearcher(jp.getIndexDir());
Analyzer analyzer = SpanishAnalyzer.getInstance();
QueryParser parser = new QueryParser("Fecha", analyzer);
Query query = parser.parse(rangeDate);
final List<Integer> tempHits = new ArrayList<Integer>();
searcher.search(query, new HitCollector() {
@Override
public void collect(int doc, float score) {
tempHits.add(doc);
}
});
List<Integer> hits = new ArrayList<Integer>();
for (int i = tempHits.size() - 1; i >= 0 ; i--) {
hits.add(tempHits.get(i));
}
docsID = new Integer[searcher.maxDoc()];
docsID = hits.toArray();
} catch (Exception e) {
throw e;
}
return docsID;
}

En este ejemplo se quiere obtener todos los documentos del ndice. Como artificio se busca por un rango de
fecha absurdo y el searcher devuelve todos los documentos en orden.
4.4

Dar formato a los resultados


En los ejemplos anteriores solo se obtuvo los IDs de los documentos o scoreDocs, pero que se hace luego
con ellos? En este proyecto se necesito extraer el contenido de los documentos ms darle un formato
especial al contenido de los archivos. Para ello se muestra el siguiente cdigo:

Confidencial

UPC, 2015

Page 9 of 11

Conocimiento en Lnea
Lucene: Tutorial
Conocimiento-en-Linea - Lucene: Tutorial

Version:
0.2
Date: 06/03/2009

private void FillPage(Object[] hits) throws Exception {


QueryParser parser = new QueryParser("Contenido", SpanishAnalyzer.getInstance());
Query query = parser.parse(searchField);
SimpleHTMLFormatter luceneFormatter = new SimpleHTMLFormatter(
"<b><span class=\"luceneHit\">", "</span></b>");
Highlighter highlighter = new Highlighter(luceneFormatter,
new QueryScorer(query));
List<Hit> list = new ArrayList<Hit>();
for (int i = 0; i < hits.length; i++) {
ScoreDoc scoreDoc = (ScoreDoc)hits[i];
int docId = scoreDoc.doc;
Hit hit = new Hit();
IndexSearcher searcher = new
IndexSearcher(ConfigSingleton.getInstance().getIndexDir());
Document doc = searcher.doc(docId);
String text = doc.get("Contenido");
TokenStream tokenStream = TokenSources.getAnyTokenStream(
searcher.getIndexReader(), docId, "Contenido",
SpanishAnalyzer.getInstance());
int maxNumFragments = Integer.valueOf(ConfigSingleton.getInstance()
.getMaxNumFragments());
text = highlighter.getBestFragments(tokenStream, text,
maxNumFragments, "...");
hit.setContent(text);
hit.setPath(ConfigSingleton.getInstance().getRepositoryURL() + doc.get("Ruta"));
hit.setName(doc.get("Nombre"));
list.add(hit);
}
httpSession.setAttribute("hits", list.toArray());
}
Lo importante de este cdigo es que se usa la clase SimpleHTMLFormatter, Highlighter y TokenStream
para poder darle formato al resultado. En este proyecto se necesito mostrarse un fragmento del contenido
del documento y ese fragmento necesitaba contener pequeos fragmentos del texto justo en donde estaban
las palabras que se buscaron. Con SimpleHTMLFormatter se inserta el cdigo HTML que se desee
alrededor de la palabra con que se busco. Finalmente, el mtodo highlighter.getBestFragments() se
encarga de filtrar el texto.

5.

Parsers
Un parser se encarga de extraer el contenido de un archivo como PDF, Word, PPTs, etc y convertirlo a texto
puro. Si bien es cierto que los parsers no vienen dentro del paquete de lucene, se pueden conseguir parsers
en otras libreras.
A continuacin se muestra un ejemplo de parser usado en este proyecto:

Confidencial

UPC, 2015

Page 10 of 11

Conocimiento en Lnea
Lucene: Tutorial
Conocimiento-en-Linea - Lucene: Tutorial

Version:
0.2
Date: 06/03/2009

PDF:
package conocimientoenlinea.parse;
import java.io.File;
import java.io.FileInputStream;
import java.io.StringWriter;
import org.pdfbox.pdmodel.PDDocument;
import org.pdfbox.util.PDFTextStripper;
public class PDF {
public static String Parse(File archivo) throws Exception {
PDDocument pdfDocument = null;
String contents = null;
try {
pdfDocument = PDDocument.load(new FileInputStream(archivo));
if (pdfDocument.isEncrypted()) {
pdfDocument.decrypt("");
}
StringWriter writer = new StringWriter();
PDFTextStripper stripper = new PDFTextStripper();
stripper.writeText(pdfDocument, writer);
contents = writer.getBuffer().toString();
} catch(Exception e) {
throw new Exception();
} finally {
if (pdfDocument != null) {
pdfDocument.close();
}
}
return contents;
}
}

Confidencial

UPC, 2015

Page 11 of 11

También podría gustarte