9. Datos no estructurados
9.1 Introducción
Colecciones no estructuradas
• Datos sin tipos pre-definidos
• Se almacenan como “documentos”
u “objetos” sin estructura
uniforme
• Se recuperan con apoyo
de índices ymodelos
de “RI” para determinar su relevancia respecto a consultas del
usuario
• Ejemplos:
- Correspondencia, diarios, novelas,
blogs
Recuperación de Información
(RI)
• Area de las ciencias computacionales
que estudia técnicas y métodos para indexar y consultar colecciones
de diversos niveles de estructura
• Proceso para determinar
los documentos relevantes para un
tema especificado por el usuario
– Ejemplo:
“Encontrar documentos sobre
historia de los juegos olímpicos”
– El problema involucra interpretar,
comparar, jerarquizar,…
• Comparar con recuperación
de datos:
– Obtención de todos
los elementos en una colección que satisfacen totalmente
condiciones claramente especificadas.
Ejemplo: Encontrar los nombres de
todos los estudiantes de la
carrera de ISC
– El problema es sencillo
si se cuenta con una base de datos relacional:
• select
nombre from estudiantes where carrera = ‘IS’
RI cobra importancia
• Se inicia con tablas de
contenido e índices de libros
• Las bibliotecas introdujeron
índices a múltiples publicaciones,
referencias cruzadas e índices jerárquicos para
clasificar documentos
• Desde los 40s, se inicia
RI orientado a indexar y recuperar textos
pero la recuperación de datos domina
• En los 90s, el desarrollo
de WWW hace de RI un área fundamental
y acelera su evolución
• RI incluye ahora modelado,
indexado, clasificación, interfaces de usuario, visualización
de datos textuales, multimediales e hipertextuales
• Meta: Dada una consulta,
obtener todos los documentos relevantes posibles y minimizar
el número de documentos irrelevantes
El reto
• El enfoque inicial: clasificar
documentos
• El problema: quien categoriza
no coloca los documentos donde espera encontrarlos quien busca,
a veces ni el mismo clasificador (ej. archivos personales, folders
de correo electrónico)
• Otro enfoque: “entender”
el contenido y responder a consultas
• Problema: El procesamiento
de lenguaje natural aún no es lo suficientemente
general (¿ni lo será?)
• La alternativa: RI, basada
en reconocimiento de patrones, muestreo
estadístico, aprendizaje maquinal, probabilidad,…
• La meta de RI: encontrar
documentos relevantes rápidamente
• RI será un área de investigación
mientras los métodos existentes no
sean suficientemente efectivos
y eficientes simultáneamente
Medidas de efectividad de RI
• Precisión (o “especificidad”)
• Cobertura (o “exhaustividad”)
Visión Lógica de los Documentos
Es la representación de documentos y/o páginas
web que forman parte de una colección (sistema de IR).
-
La forma más común de representar un documento
de texto es por un sistema de términos indexados o palabras llaves.
Estos términos son extraídos con el siguiente
proceso:
-
Para la lematización los "stopwords" generalmente
se utilizan listas de palabras, ya sean de un lenguaje controlado (alguna
especialidad) o bien de un idioma particular.
Por otro lado para realizar el “stemming” (reducir palabras de su raíz
gramatical) se emplea el algoritmo de Porter, solo que hay que tener en
cuenta el idioma a utilizar ya que por lo general se encuentra en inglés
aunque hay versiones para español.
http://www.tartarus.org/~martin/PorterStemmer/
Existen 2 tipos de tareas principales en la recuperación de
información:
-
Las centradas en la computadora: consiste en construir un
índice eficiente, procesar las consultas del usuario con un
alto rendimiento y algoritmos (modelos de recuperación) que
mejoren la calidad de respuesta del sistema.
-
Las centradas en el humano: consiste principalmente en estudiar
las necesidades del usuario, saber cómo afecta a la organización,
operación y visualización de resultados en el sistema
de recuperación.
9.2 Modelos de Recuperación
Modelos clásicos
de RI
• Booleano, vectorial y probabilístico
• Diseñados para colecciones de texto
• El modelo lógico de los documentos consiste de
“términos” o palabras que se refieren (indexan) al tema
principal tratado
• Algunas propiedades útiles:
- Los términos que aparecen en casi todos los documentos no
son útiles
- Algunos términos pueden tener mayor relevancia con respecto
a un documento dado, lo que se puede denotar por un
“peso” del término
- Para un término ki y un documento dj, wi,j >=0 denota
la importancia del término para describir el contenido
del documento
- Para una colección con t términos, puede definirse el vector
Dj = (w1,j, w2,j,… wt,j)
9.2.1 Clasificación
-
9.2.2 Modelo Booleano
El modelo Boleano, es un modelo de recuperación simple
basado en la teoría fija y álgebra de Boolean, este modelo
proporciona un grupo de trabajo que es fácil de usar por un usuario
común de un sistema de IR. Además, las llamadas se especifican
como expresiones de Boolean que tienen la semántica precisa.
Dado su simplicidad inherente y formalismo, el modelo de Boolean
recibió la gran atención y se adoptó por muchos de
los sistemas bibliográficos comerciales.
De este modelo se pueden destacar los siguientes puntos:
-
La relevancia es binaria: un documento es relevante o no
lo es.
-
Consultas de una palabra: un documento es relevante si contiene
la palabra.
-
Consultas AND: Los documentos deben contener todas las palabras.
-
Consultas OR: Los documentos deben contener alguna palabra.
-
Consultas A BUTNOT B: Los documentos los documentos deben
ser relevantes para A pero no para B.
· Ejemplo: lo mejor
de Maradona
Maradona AND Mundial
AND (( México ’86 OR Italia ’90) BUTNOT U.S.A. ’94)
-
Es el modelo mas primitivo, sin embargo es el mas popular.
¿Por qué es malo?
-
No discrimina entre documentos más y menos relevantes.
-
Da lo mismo que un documento contenga una o cien veces las
palabras de consulta.
-
Da lo mismo que cumpla una o todas las cláusulas
de un OR.
-
No permite ordenar los resultados.
-
Puede resultar confuso
Ejemplo: Necesito investigar sobre los Aztecas y los Incas
Aztecas AND Incas
(cuando en realidad lo que se pretendía era: Aztecas OR Incas).
¿Por qué es popular?
-
Es una de los primeros modelos que se implemento y muchos
de los primeros sistemas de IR se basaron en él
-
La idea suele ser común entre los usuarios que la
están usando.
-
Es la opción favorita para insertar texto en un RDBMS.
-
Es simple de formalizar y eficiente de implementar.
-
En algunos caso (usuarios expertos) puede ser adecuado.
-
Puede ser útil en combinación con otro modelo
ej. Para excluir documentos.
-
Puede ser útil con buenas interfaces.
Tablas posibles para
el modelo booleano
• Docs (IdDoc,
NombreDoc, FechaPub, …, texto)
• IndiceInv
(IdDoc, Term)
• Consulta
(Term) |
• Un pre-proceso puede
producir Docs (extrayendo
datos de archivos) e
IndiceInv
(vía parser, lematización, eliminación de palabras vacías)
Uso de SQL para el
modelo booleano
• Encontrar los
ids de documentos que contengan los
término “casa” o “blanca”
– select distinct
IdDoc from IndiceInv
where term = ‘casa’ or
term = ‘blanca’
• Recuperar el
texto de los documentos…
– select texto
from Docs
where IdDoc in
(select distinct IdDoc
from IndiceInv
where term = ‘casa’ or
term = ‘blanca’)
• ¿Cómo
se obtendrían los documentos que contienen
“casa” y “blanca”?
|
SQL para el modelo booleano
• “AND” usando
agregación y agrupación:
– select IdDoc
from IndiceInv i, Consulta q
where i.term = q.term
group by i.IdDoc
having count(i.term) =
(select count(*) from Consulta)
• en este caso,
“where” asegura que se incluyen los términos pedidos,
“group by” agrupa
los términos para cada documento,
y “having” que haya tantos
términos en el documento como en la consulta
|
9.2.3 Modelo de Espacios Vectoriales
8.2.3.1 Introducción
• Propuesto en 1975, hoy el más popular (con variantes)
• También llamado solamente “modelo vectorial”
• Generaliza el modelo booleano al manejar pesos
no binarios para los términos de cada documento y de la
consulta (query)
• Determina la similitud entre la consulta y cada
documento calculando el ángulo entre sus vectores
• La idea principal es que dos documentos son similares
si sus vectores apuntan hacia la misma dirección
• Un aspecto importante es la determinación del
peso de cada término, típicamente basado en su frecuencia:
- el peso aumenta entre más ocurre en un documento dado
- el peso disminuye entre más aparece en los demás
documentos
8.2.3.2 Algoritmo
Uso de frecuencia inversa (TFIDF)
• Considerando
– n = número de términos distintos en una colección
– tfij = número de ocurrencias en el documento
i del término tj
– dfj = número de documentos que contienen tj
– idfj = log(d/dfj) = frecuencia inversa de documentos,
donde d es el número total de documentos
• entonces cada vector tiene n componentes
• para una gran colección de documentos pequeños,
los vectores contendrán muchos ceros
• un cálculo del peso para el j-ésimo elemento
del documento di es:
• la similitud entre una consulta Q y un documento
Di puede definirse
como el producto de los dos vectores:
En 1988 Salton y Buckley proponen modificaciones a las medidas originales,
sugiriendo la siguiente fórmula para el cálculo de pesos del término
j en el documento i. Esta variación se debió al argumento de que un
match de un término con una frecuencia muy alta puede distorcionar a
los demás matches entre el query y el documento.
Similarity Measures
Para medir la similitud entre los vectores formados por el query
y cada documento existen muchas formulas, siendo la del coseno la
más popular, ya que de una manera simple calcula el ángulo entre ambos
vectores.
Conceptos Iniciales:
Teoría de Vectores
-
Tablas posibles para el
modelo vectorial
• Docs
(IdDoc, NombreDoc, FechaPub, …, texto)
• IndiceInv
(IdDoc, Term, tf)
• Terms
(term, idf)
• Consulta
(term, tf) |
• Un pre-proceso puede producir
Docs (extrayendo
datos de archivos) e
IndiceInv
(vía parser, lematización, eliminación de palabras vacías)
• Terms
puede producirse mediante:
– insert into terms
select term, log(N/count(*))
from IndiceInv
group by term
• donde N es el número total
de documentos y se conoce o se puede obtener
previamente (select count(*) from Docs)
• Consulta
es solamente una representación tabular de la petición del usuario
para facilitar el cálculo del índice de similitud
SQL para espacios vectoriales
usando TFIDF
• select i.IdDoc,
sum(q.tf * t.idf * i.tf * t.idf)
from consulta q, IndiceInv
i, Terms t
where q.term = t.term
and i.term = t.term
group by i.IdDoc
order by 2 desc
• “where” garantiza
que se incluyen sólo terminos de
la consulta,
“order by”, que se ordenan
según el coeficiente de similitud
|
Cálculo del coseno del ángulo
• Tablas intermedias:
– pesos_docs(IdDoc,
peso)
– peso_q(peso) |
• Generación de tablas intermedias:
– insert into pesos_docs
select IdDoc, sqrt(sum(i.tf
* t.idf * i.tf * t.idf))
from IndiceInv i, Terms t
where i.term = t.term
group by IdDoc
– insert into peso_q
select sqrt(sum(q.tf * t.idf
* q.tf * t.idf ))
from consulta q, Terms t
where q.term = t.term
|
Cálculo del coseno del ángulo
• select
i.IdDoc, sum(q.tf * t.idf * i.tf * t.idf) / (dw.peso * qw.peso)
from consulta q, IndiceInv
i, terms t,
pesos_docs dw, peso_q qw
where q.term = t.term AND
i.term = t.term AND
i.IdDoc = dw.IdDoc
group by i.IdDoc, dw.peso,
qw.peso
order by 2 desc
|
9.2.3.3 Herramientas
Producto |
Lenguaje |
Modelos |
Indexamiento |
API desarrollo |
Licencia |
Managing Gigabytes |
C/C++, envoltura Java |
Vectorial |
Propietario |
Ninguno |
Open Source |
Xapian |
C/C++ |
Probabilístico |
Propietario |
Limitado |
Open Source |
Lucene |
Java |
Vectorial |
Propietario |
Abierto y extendible |
Open Source |
MySQL FullText |
C/C++ Java
(SMART) |
Vectorial |
Propietario ISAM |
SQL |
Open Source |
Egothor |
Java |
Booleano Extendido |
Propietario |
Ninguno |
Open Source |
MySQL Fulltext
Creación de tabla y utilización de Match
mysql> CREATE TABLE articles ( -> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, -> title VARCHAR(200), -> body TEXT, -> FULLTEXT (title,body) -> ); Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO articles VALUES -> (NULL,'MySQL Tutorial', 'DBMS stands for DataBase ...'), -> (NULL,'How To Use MySQL Efficiently', 'After you went through a ...'), -> (NULL,'Optimising MySQL','In this tutorial we will show ...'), -> (NULL,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), -> (NULL,'MySQL vs. YourSQL', 'In the following database comparison ...'), -> (NULL,'MySQL Security', 'When configured properly, MySQL ...'); Query OK, 6 rows affected (0.00 sec) Records: 6 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM articles -> WHERE MATCH (title,body) AGAINST ('database'); +----+-------------------+------------------------------------------+ | id | title | body | +----+-------------------+------------------------------------------+ | 5 | MySQL vs. YourSQL | In the following database comparison ... | | 1 | MySQL Tutorial | DBMS stands for DataBase ... | +----+-------------------+------------------------------------------+ 2 rows in set (0.00 sec)
Mostrar los resultados incluyendo la relevancia de cada uno
mysql> SELECT id,MATCH (title,body) AGAINST ('Tutorial') FROM articles; +----+-----------------------------------------+ | id | MATCH (title,body) AGAINST ('Tutorial') | +----+-----------------------------------------+ | 1 | 0.64840710366884 | | 2 | 0 | | 3 | 0.66266459031789 | | 4 | 0 | | 5 | 0 | | 6 | 0 | +----+-----------------------------------------+ 6 rows in set (0.00 sec)
Ejemplo que recupera los resultados y sus scores
de similitud.
mysql> SELECT id, body, MATCH (title,body) AGAINST -> ('Security implications of running MySQL as root') AS score -> FROM articles WHERE MATCH (title,body) AGAINST -> ('Security implications of running MySQL as root'); +----+-------------------------------------+-----------------+ | id | body | score | +----+-------------------------------------+-----------------+ | 4 | 1. Never run mysqld as root. 2. ... | 1.5055546709332 | | 6 | When configured properly, MySQL ... | 1.31140957288 | +----+-------------------------------------+-----------------+ 2 rows in set (0.00 sec)
Con la versión 4.0.1 se pueden
hacer búsquedas a texto completo incluyendo operadores
booleanos.
mysql> SELECT * FROM articles WHERE MATCH (title,body) -> AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE); +----+------------------------------+-------------------------------------+ | id | title | body | +----+------------------------------+-------------------------------------+ | 1 | MySQL Tutorial | DBMS stands for DataBase ... | | 2 | How To Use MySQL Efficiently | After you went through a ... | | 3 | Optimising MySQL | In this tutorial we will show ... | | 4 | 1001 MySQL Tricks | 1. Never run mysqld as root. 2. ... | | 6 | MySQL Security | When configured properly, MySQL ... | +----+------------------------------+-------------------------------------+
|
Lucene
Características
- Concurrencia
- Diferentes "ports": Perl, Python, C++, .Net, Ruby
- Scoring
Diferentes tipos de Fields
public Field(String name, String value, Field.Store store, Field.Index index)
- Create a field by specifying its name, value and how it will be saved in the index. Term vectors will not be stored in the index.
Parameters:
- name - The name of the field
- value - The string to process
- store - Whether value should be stored in the index
Field Summary |
static Field.Store |
COMPRESS
Store the original field value in the index in a compressed form. |
static Field.Store |
NO
Do not store the field value in the index. |
static Field.Store |
YES
Store the original field value in the index. |
- index - Whether the field should be indexed, and if so, if it should be tokenized before indexing
Field Summary |
static Field.Index |
NO
Do not index the field value. |
static Field.Index |
NO_NORMS
Index the field's value without an Analyzer, and disable the storing of norms. |
static Field.Index |
TOKENIZED
Index the field's value so it can be searched. |
static Field.Index |
UN_TOKENIZED
Index the field's value without using an Analyzer, so it can be searched. |
Fields en las versiones anteriores (< 2.0):
Field method type |
Analyzed |
Indexed |
Stored |
Usage |
Field.Keyword(String, String)
Field.Keyword(String, Date) |
|
X |
X |
Telephone and Social Security numbers, URLs, personal
names
Dates |
Field.Unindexed(String,String) |
|
|
X |
Document type (pdf, html, etc), if not used as a
search criteria |
Field.Unstored(String, String) |
X |
X |
|
Document titles and content |
Field.Text(String, String) |
X |
X |
X |
Document titles and content |
Field.Text(String, Reader) |
X |
X |
|
Document titles and content |
Core Classes
- IndexWriter: crea el índice y agrega documentos a éste
- Directory: la ubicación del índice, se puede tener un FSDirectory
o un RAMDirectory, dependiendo si se desea tener dicho índice en disco
o en memoria
- Analyzer: proceso que analiza y limpia el texto (stop words, stemming)
antes de que sea indexado
- Document: una colección de Fields
- Field: pareja de un nombre y valor, con que sirven para identificar
las distintas partes de un documento; estas parejas pueden ser tan simples
como "id" y "234" o bien tan complejas como texto
completo "contenido" y "Había una vez...."
- IndexSearcher: abre y emplea el índice en read-only para realizar
las búsquedas
- Term: unidad básica de búsqueda (son creados por el indexer)
- Query: distintas subclases para crear queries, BooleanQuery, PhraseQuery,
RangeQuery, etc.
- TermQuery: un Term asociado a un query el cual puede poseer un nivel
de "boost" para darle mayor peso sobre otros términos
- Hits: contenedor de apuntadores hacia los resultados ranqueados de
una búsqueda
Ejemplo de programación con Lucene
/*
* JUIRDBC.java
*
*
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package juirdbc;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Vector;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.DateTools;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.TermEnum;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Searcher;
/**
* Class to serve between applications and index files to use retrieval models
* with or without Hermes easier
*
*@author carlos
*@created April 16, 2003
*/
public class JUIRDBC {
private String indexfile;
private boolean store;
/**
* Constructor for the JUIRDBC object
*
*@param indexfile Index file to store/retrieve terms information
*@param store true store full documents too, false just store terms
*/
public JUIRDBC(String indexfile, boolean store) {
this.indexfile = indexfile;
this.store = store;
}
/**
* Gets a lucene Document of the specified id, A document contain the some
* section, identifies by a name This means that even we chose not to store
* the document we will have a result
*
*@param id Unique identifier of the resource
*@return org.apache.lucene.document.Document value, null
* if resource doesnt exist
*@exception IOException Exception
*/
public org.apache.lucene.document.Document getResource(String id) throws IOException {
IndexReader ireader = IndexReader.open(indexfile);
TermDocs tdocs = ireader.termDocs(new Term("id", id));
if (tdocs.next()) {
return ireader.document(tdocs.doc());
}
return null;
}
/**
* Gets a list of all the resources(ids) in current index
*
*@return vector containing ids
*@exception IOException Exception
*/
public Vector getListResources() throws IOException {
Vector vector = new Vector();
IndexReader r = IndexReader.open(indexfile);
int num = r.numDocs();
for (int i = 0; i < num; i++) {
if (!r.isDeleted(i)) {
org.apache.lucene.document.Document d = r.document(i);
vector.add(d.get("id"));
}
}
TermEnum te = r.terms();
int w = 0;
while (te.next()) {
w++;
}
System.out.println(w);
r.close();
return vector;
}
/**
* Establish connection with a index service Currently just initialize the
* file because there is no such service
*
*@exception IOException Description of Exception
*/
public void openConnection() throws IOException {
if (IndexReader.indexExists(indexfile) == false) {
IndexWriter writer = new IndexWriter(indexfile, new StandardAnalyzer(), true);
writer.close();
}
}
/**
* Termines communication with index service
*
*@exception IOException Exception
*/
public void closeConnection() throws IOException { }
/**
* Adds a resource (or terms of) to the index file
*
*@param id Unique identifier of the resource
*@param file Resource/document to be added
*@exception IOException Exception
*/
public void addResource(String id, File file) throws IOException {
IndexWriter writer = new IndexWriter(indexfile, new StandardAnalyzer(), false);
writer.addDocument(fileToDocument(id, file));
writer.optimize();
writer.close();
}
/**
* Removes a resource (and/or its terms) from the index file
*
*@param id id of document to be deleted
*@exception IOException Exception
*/
public void deleteResource(String id) throws IOException {
IndexReader ireader = IndexReader.open(indexfile);
TermDocs tdocs = ireader.termDocs(new Term("id", id));
if (tdocs.next()) {
ireader.deleteDocument(tdocs.doc());
}
ireader.close();
}
/**
* Search a query with lucene
*
*@param line string of terms to be searched
*@return lucene hits
*@exception Exception Exception
*/
public Hits search(String line) throws Exception {
Searcher searcher = new IndexSearcher(indexfile);
Analyzer analyzer = new StandardAnalyzer();
QueryParser parser=new QueryParser("contents",analyzer);
Query query = parser.parse(line);
System.out.println("Searching for: " + query.toString("contents"));
return searcher.search(query);
}
/**
* Converts a file to Lucene's specification of Document The document
* contains two fields: id - the document id contents - file content
*
*@param id identifier of current document
*@param f file to be added
*@return Document Value
*@exception java.io.FileNotFoundException Exception
*/
private org.apache.lucene.document.Document fileToDocument(String id, File f)
throws java.io.FileNotFoundException {
// make a new, empty document
org.apache.lucene.document.Document doc = new org.apache.lucene.document.Document();
doc.add(new Field("id", id,Field.Store.YES,Field.Index.TOKENIZED));
// Add the path of the file as a field named "path". Use a Text field, so
// that the index stores the path, and so that the path is searchable
doc.add(new Field("path", f.getPath(),Field.Store.YES,Field.Index.TOKENIZED));
// Add the last modified date of the file a field named "modified". Use a
// Keyword field, so that it's searchable, but so that no attempt is made
// to tokenize the field into words.
doc.add(new Field("modified",
DateTools.timeToString(f.lastModified(),DateTools.Resolution.YEAR),
Field.Store.YES,
Field.Index.TOKENIZED));
// Add the contents of the file a field named "contents". Use a Text
// field, specifying a Reader, so that the text of the file is tokenized.
// ?? why doesn't FileReader work here ??
FileInputStream is = new FileInputStream(f);
Reader reader = new BufferedReader(new InputStreamReader(is));
try {
char[] documento = new char[new Long(f.length()).intValue()];
FileReader freader = new FileReader(f);
freader.read(documento, 0, new Long(f.length()).intValue());
if (store) {
doc.add(new Field("contents",
new String(documento),
Field.Store.YES,
Field.Index.TOKENIZED));
} else {
doc.add(new Field("contents", reader));
}
} catch (Exception e) {
}
// return the document
return doc;
}
} |
|
|
/*
* Main.java
*
*
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package example;
import java.io.File;
import juirdbc.JUIRDBC;
import org.apache.lucene.document.Document;
import org.apache.lucene.search.Hits;
/**
*
* @author digital
*/
public class Main {
/** Creates a new instance of Main */
public Main() {
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
if(args.length<1) {
System.err.println("Falta incluir la busqueda entre comillas, ej \"xml arbol xsl fo\"");
return;
}
try {
File dir=new File("lucene.idx");
if(dir.exists()) {
File files[]=dir.listFiles();
for(int j=0;j<files.length;j++)
files[j].delete();
}
JUIRDBC lucene=new JUIRDBC("lucene.idx",true);
lucene.openConnection();
lucene.addResource("syllabus",new File("D:\\digital\\Desktop\\bda\\syllabus.html"));
lucene.addResource("01",new File("D:\\digital\\Desktop\\bda\\bda01.html"));
lucene.addResource("02",new File("D:\\digital\\Desktop\\bda\\bda02.html"));
lucene.addResource("03",new File("D:\\digital\\Desktop\\bda\\bda03.html"));
lucene.addResource("04",new File("D:\\digital\\Desktop\\bda\\bda04.html"));
lucene.addResource("05",new File("D:\\digital\\Desktop\\bda\\bda05.html"));
lucene.addResource("06",new File("D:\\digital\\Desktop\\bda\\bda06.html"));
lucene.addResource("07",new File("D:\\digital\\Desktop\\bda\\bda07.html"));
lucene.addResource("08",new File("D:\\digital\\Desktop\\bda\\bda08.html"));
lucene.addResource("09",new File("D:\\digital\\Desktop\\bda\\bda09.html"));
lucene.addResource("10",new File("D:\\digital\\Desktop\\bda\\bda10.html"));
if(args.length==1) {
Hits hits=lucene.search(args[0]);
for(int i=0;i<hits.length();i++) {
Document doc=hits.doc(i);
System.out.println(hits.score(i)+" "+hits.id(i)+" "+doc.getField("id")+" "+doc.getField("path"));
}}
lucene.closeConnection();
}catch(Exception e) {
e.printStackTrace(); }
}
} |
|
|
Uso de vectores para encontrar similitudes con Lucene (fragmento
cap.5 Lucene in Action)
|