Lucene para ASP.NET (Parte III). Búsqueda.

23 jul. 2008
Siguiendo la serie de artículos sobre Lucene (Lucene para ASP.NET (Parte I). Introducción y Lucene para ASP.NET (Parte II). Indexación), dónde conocimos qué era Lucene y cómo indexar contenidos, durante este artículo vamos a hablar de la búsqueda, sin duda, el objetivo último que perseguimos.

Según la estructura del Document planteada en el artículo sobre Indexación, cuando queramos buscar algo atacaremos a los campos "Title" y "Text", pues son los que contendrán la información importante. Es decir, lo que queremos es "buscar palabras que se encuentran en el título o en el texto".

A continuación tenemos un método que busca en ambos campos y devuelve un listado de Document's:

public static List<Document> SearchDocuments(string sQuery)
{
    // Creamos el listado documents que vamos a devolver
    List<Document> documents = new List<Document>();
   
    // Abrimos el IndexSearcher con el Path del directorio que  hace de índice. Aquí usamos una variable global.
    IndexSearcher searcher = new IndexSearcher(IndexPath);

    try
    {
        // Buscamos en Text
        QueryParser qpText = new QueryParser("Text", new SpanishAnalyzer());
        Query queryText = qpText.Parse(sQuery);

        // Buscamos en Title
        QueryParser qpTitle = new QueryParser("Title", new SpanishAnalyzer());
        Query queryTitle = qpTitle.Parse(sQuery);

        // Unimos ambos elementos: queremos que nuestro query se encuentre en uno de los dos sitios.
        // Si puede ser en los dos, mejor.
        BooleanQuery bq = new BooleanQuery();
        bq.Add(queryText, BooleanClause.Occur.SHOULD);
        bq.Add(queryTitle, BooleanClause.Occur.SHOULD);

        // La clase Hits es la clave. Es lo que nos devolverá la Search
        Hits hits = searcher.Search(bq);
        int totalHits = hits.Length();

        // Recorremos todos los Hits, recogemos el document y lo añadimos a nuestro listado genérico
        // Aquí es donde debería hacerse la paginación, etc.
        for (int i = 0; i < totalHits; i++)
        {
            Document document = hits.Doc(i);
            documents.Add(document);
        }
    }
    finally
    {
        searcher.Close();
    }

    return documents;
}

Como vemos, el código se autoexplica bastante.

Lo más importante es saber que QueryParser define dónde queremos buscar y con qué Analyzer, y Query define qué queremos buscar.

Con el BooleanQuery uniremos las búsquedas en ambos campos, indicándole mediante el SHOULD que los resultados deben encontrarse en al menos uno de los dos campos (Title o Text), pero que si puede ser en los dos, mejor que mejor.

Los resultados tras el searcher.Search(...) vienen en forma de Hits. Los Hits contienen el Document, pero también contienen otros campos interesantes como el Score que devuelve la puntuación de 0 a 100 o el Length que devuelve el número de resultados encontrados.

Como véis esto ha sido una búsqueda a pelo. Ahora quedaría paginar, filtrar los resultados con Score bajo, etc.
comments powered by Disqus
subir