O artigo apresenta os componentes comumente encontrados em mecanismos de buscas modernos e como o framework Apache Lucene pode auxiliar na construção de soluções desse tipo. Uma aplicação de cadastro e busca de currículos é utilizada para demonstração dos recursos da biblioteca.
Em que situação o tema é útil:
O tema é útil nas situações em que o usuário precisa realizar buscas complexas sobre os dados de uma aplicação. Implementações de buscas tradicionais, baseadas em consultas SQL ou na leitura sequencial do conteúdo de arquivos, são limitadas e podem ter um desempenho ruim. Outras abordagens são necessárias, tais como a apresentada pelo Lucene.
Resumo DevMan:
O Lucene baseia-se no conceito de índices, estruturas de dados que permitem que qualquer termo e as suas localizações dentro do conteúdo sejam encontrados rapidamente. As suas classes dividem-se grosseiramente naquelas que são utilizadas para a construção do índice e naquelas que, utilizando o índice, são capazes de realizar buscas eficientes sobre o conteúdo. O Lucene é um framework de baixo nível e, como tal, exige um bom conhecimento de seus conceitos para o seu correto uso na aplicação.
Autores: Paulo Sigrist e Wilson Akio Higashino
A existência de bons mecanismos de busca nas aplicações que utilizamos é fundamental para nosso dia-a-dia. Com o aumento da quantidade de informações que produzimos e consumimos, é cada vez mais importante sermos capazes de localizar a informação correta de maneira fácil, rápida e intuitiva.
O que seria da Internet se não existissem os poderosos motores de busca como o Google e o Bing? De fato, pouco importa a existência de muita informação se não somos capazes de localizá-la. É interessante notar também que não só na Internet as buscas têm exercido esse papel tão fundamental. Sistemas Desktop, como o Mac OS X e o Windows, já integram mecanismos que permitem localizar rapidamente arquivos e recursos pelo seu nome, conteúdo e inúmeros outros filtros. Aplicações tradicionais, como tocadores de mídias e clientes de e-mail, também possuem motores de busca, e até mesmo Smartphones iOS e Android já possuem implementações desses recursos. De certa forma, isso demonstra não só o aumento do volume de informações que produzimos, mas também que o paradigma usualmente utilizado para organizá-las, baseado em arquivos e diretórios, não é suficiente para nossas necessidades atuais.
Tradicionalmente, implementamos buscas em nossas aplicações através de consultas SQL, executadas por Sistemas Gerenciadores de Banco de Dados (SGBDs). Todavia, esta abordagem possui uma série de limitações. Ela implica, por exemplo, na existência de um SGDB capaz de executar essas consultas. Além disso, nem sempre é fácil transformar uma série de filtros em SQL. Observe, por exemplo, a variedade de consultas que o Google fornece e imagine como elas poderiam ser transformadas em comandos select. Finalmente, o desempenho de tais consultas nem sempre é compatível com o requerido pela aplicação. Consultas por substrings em colunas de tipo texto são um pesadelo para muitos DBAs e costumam ser evitadas, já que impactam profundamente no desempenho do SGDB.
Pensando nisso, esse artigo apresenta o Apache Lucene, um framework de código aberto poderoso e flexível que pode ser usado para a construção de mecanismos de buscas e para a integração destes com aplicações Java de diversas naturezas. Vamos apresentar os seus conceitos básicos através de uma aplicação de cadastro e busca de currículos.
Componentes de um mecanismo de busca
Antes de entendermos o que o Lucene faz, vale a pena revisar os componentes que tradicionalmente compõem um mecanismo de busca. A Figura 1 contém uma representação em alto nível dos componentes principais.
Em um extremo da figura temos o conteúdo propriamente dito, e em outro os usuários que desejam realizar pesquisas sobre esse conteúdo. Para que a busca seja feita de forma rápida e eficiente, os mecanismos de busca baseiam-se nos chamados índices, que são estruturas de dados que permitem que os termos sejam localizados rapidamente, assim como os locais dentro do conteúdo nos quais os termos são encontrados. No entanto, índices são estruturas complexas, cuja construção exige grande poder computacional. Assim, é comum dividirmos as aplicações de busca em dois grandes grupos de funcionalidades: a construção do índice e as consultas que são realizadas com o seu auxílio.
Figura 1. Componentes de uma aplicação de busca (adaptado de [4]).
Para a construção do índice, o primeiro passo consiste na etapa de aquisição do conteúdo. Por exemplo: o Google possui robôs, chamados de crawlers, que navegam pela Web a procura de novas páginas a serem indexadas. Em outros casos, essa etapa é muito mais simples: em um cliente de e-mail o conteúdo são as próprias mensagens dos usuários, que podem ser acessados diretamente pela aplicação.
Uma vez obtido o conteúdo, eles são transformados nos chamados “documentos”, que nada mais são que representações canônicas, definidas pelo mecanismo de busca, e que representam o conteúdo obtido. Por exemplo: as buscas embutidas nos sistemas operacionais são capazes de encontrar palavras-chave em arquivos PDF, documentos Word ou até mesmo em mensagens armazenadas em clientes de e-mail. Portanto, nesta etapa do processo de indexação, todos esses diferentes tipos de documentos são convertidos para um formato comum, normalmente composto por um conjunto de campos padronizados, tais como autor, data de criação e o próprio conteúdo.
Em seguida, esses documentos são analisados a fim de tornar o índice mais efetivo. Alguns processamentos simples, tais como a conversão de maiúsculas para minúsculas, e a eliminação de conectivos, tais como “a”, “e” e “ou”, são comuns durante essa etapa. Todavia, outros mecanismos mais complexos também são utilizados. Por exemplo, é comum que as palavras sejam processadas a fim de reduzi-las à sua raiz morfológica. Assim, termos como “computação” e “computadores” são transformados em uma raiz comum, “computa”, permitindo que termos relacionados sejam encontrados. O resultado da análise é um conjunto de tokens, que são as “palavras” que efetivamente farão parte do índice. Esta etapa é uma das mais importantes do processo de indexação, podendo determinar o sucesso ou o fracasso da aplicação.
Por fim, a última etapa do processo de indexação alimenta o índice com os tokens obtidos a partir do documento analisado. Como todo esse processo é custoso, normalmente um conjunto de documentos dão origem a uma versão inicial do índice, que é modificado de forma incremental através de adições de novos documentos e de atualizações dos já existentes.
Já no outro extremo da arquitetura temos os usuários, que interagem com a aplicação através de uma interface na qual ele entra com a busca desejada. Em seguida, há uma etapa em que a entrada do usuário é convertida para uma consulta em um formato definido pelo mecanismo de busca. Como uma analogia, pense na conversão de um filtro para uma consulta SQL a ser executada em um banco de dados.
A consulta é então executada utilizando como auxílio o índice construído anteriormente. É importante ressaltar novamente a importância do índice para uma execução eficiente da consulta. Sem ele, as buscas teriam que varrer todo o conteúdo em busca da informação requerida. Em um programa de e-mail ou em seu Desktop, o tempo necessário para essa varredura pode ser aceitável, mas para a Internet é inviável imaginarmos essa situação.
Finalizada a execução da busca, os resultados são finalmente apresentados para o usuário, geralmente ordenados por relevância ou outro critério que facilite localizar a informação desejada.
O Lucene
O Lucene é um framework que foi criado por Doug Cutting em 2000 como um projeto pessoal, mas que vem desde setembro de 2001 sendo mantido pelo grupo Apache. No momento da escrita deste artigo, sua última versão era a 3.5.0. Ele auxilia nas etapas de construção e análise de documentos, indexação, construção e execução de buscas, e o gerenciamento dos resultados. Desta maneira, a aplicação que utiliza o Lucene é ainda responsável por duas partes fundamentais: a aquisição de conteúdo e a interface pela qual o usuário irá interagir.
...