34
FACULDADE PRESIDENTE ANTÔNIO CARLOS DE CONTAGEM CURSO TECNÓLOGO EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS Implementação de Uma Máquina de Busca: “MBText” Eliene Alves de Moura Fernando Curvelo Volpato Jarbas Ivon Ugarte Rodrigo Marcone Xavier Contagem 2º semestre de 2011

Implementacao de Uma Maquina de Busca Com o Lucene

Embed Size (px)

Citation preview

Page 1: Implementacao de Uma Maquina de Busca Com o Lucene

FACULDADE PRESIDENTE ANTÔNIO CARLOS DE CONTAGEM

CURSO TECNÓLOGO EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS

Implementação de Uma Máquina de Busca:

“MBText”

Eliene Alves de Moura Fernando Curvelo Volpato

Jarbas Ivon Ugarte Rodrigo Marcone Xavier

Contagem 2º semestre de 2011

Page 2: Implementacao de Uma Maquina de Busca Com o Lucene

2

Eliene Alves de Moura

Fernando Curvelo Volpato Jarbas Ivon Ugarte

Rodrigo Marcone Xavier

Implementação de Uma Máquina de Busca:

“MBText”

Trabalho Interdisciplinar de conclusão de

Módulo apresentado como exigência parcial para conclusão do 5º período do Curso de Tecnologia em Análise e Desenvolvimento de Sistemas da UNIPAC Contagem.

Prof. Orientador: RAFAEL FELIPE DUTRA DA SILVEIRA

Contagem 2º. Semestre de 2011

Page 3: Implementacao de Uma Maquina de Busca Com o Lucene

3

SUMÁRIO 1 - INTRODUÇÃO 2 -OBJETIVO 3 -INTERDISCIPLINARIDADE 3.1 ARQUITETURA DE MÁQUINAS DE BUSCA 3.2 LINGUAGEM DE PROGRAMAÇÃO PARA WEB III 3.3 LEGISLAÇÃO APLICADA À INFORMÁTICA 4- CONCEITOS BÁSICOS 4.1-O QUE É UMA MÁQUINA DE BUSCA 4.2-PORQUE USAR UMA MÁQUINA DE BUSCA TEXTUAL 5- TIPOS DE MÁQUINAS DE BUSCA: 6-O SISTEMA DE RECUPERAÇÃO DA INFORMAÇÃO (SRI) 7- O LUCENE 5.1 5.2 5.3 8- O MBText 6.1 6.2 6.3 9- CONCLUSÃO 10- BIBLIOGRAFIA 9-ANEXOS

Page 4: Implementacao de Uma Maquina de Busca Com o Lucene

4

1-INTRODUÇÃO

A criação de uma Máquina de Busca Textual com o nome “MBText”, será desenvolvida seguindo uma sequência de estudos e implementações.

No primeiro momento realizar-se-á o levantamento dos dados e a pesquisa bibliográfica e documentação para, a posteriori, viabilizar a implementação do projeto a fim de desenvolver o software.

Visto que consiste em um trabalho acadêmico e um desenvolvimento de um produto, software, cujos prazos de seu desenvolvimento demandam certa quantidade de tempo, o mesmo será desenvolvido no corrente período. Lembrando que este projeto consiste também em um trabalho acadêmico desenvolvido por alunos do curso de Análise e Desenvolvimento de Sistemas (ADS) da UNIPAC- Contagem.

Um aspecto importante a ressaltar consiste nos softwares e linguagens de programação utilizada para desenvolver este trabalho acadêmico, aos quais são utilizados como instrumento de aprendizagem durante o curso em questão. Os principais são: JAVA, HTML dentre outros.

Outro aspecto a ser levado em conta consiste em observar o que este trabalho acadêmico foi desenvolvido no último período do curso de A.D.S. , de modo que se utilize do aprendizado de várias conceitos de várias disciplinas e utilizado de várias ferramentas aprendidas neste curto tempo de aprendizagem, pois trata-se de um curso de curta duração (tecnólogo) mas que os conceitos aprendidos foram aproveitados pelos alunos em questão e que deveu-se focar o tema proposto às disciplinas do corrente período, limitando um pouco à criatividade do corpo discente.

Page 5: Implementacao de Uma Maquina de Busca Com o Lucene

5

2-OBJETIVOS

Será desenvolvido um software que irá utilizar a biblioteca LUCENE onde serão mostrados suas funcionalidades e principais características sobre máquinas de busca.

A Máquina de Busca Textual que será criada “MBText” tem por objetivo indexar um conjunto de arquivos textuais a fim de localizar palavras e trechos dos mesmos.

Este sistema poderá, também, ser anexado em outros softwares a serem criados

em sistemas de empresas e sites. Portanto, outro objetivo se mostra intrínseco ao desenvolver do trabalho em si, o

desenvolver de um produto, não um produto qualquer mas um software, que possa entrar no mercado com condições de competir no mercado , se complementado e incorporado a sites e sistemas podendo o mesmo ser modificado, melhorado para melhor se adequar à necessidade proposta.

Page 6: Implementacao de Uma Maquina de Busca Com o Lucene

6

3-INTERDISCIPLINARIDADE

Conforme descrito no manual do trabalho interdisciplinar no corrente período: “O objetivo do trabalho interdisciplinar é integrar as disciplinas

cursadas no período, através da interdisciplinaridade, de acordo com um tema central relacionado ao eixo temático de cada módulo do curso. Tem o propósito também de interligar e conjugar os conhecimentos teóricos e práticos discorridos pelas disciplinas e a vivência prática-profissional dos docentes e alunos.” (UNIPAC. 2ºsemestre-2011)

3.1 ARQUITETURA DE MÁQUINAS DE BUSCA

A partir do momento que se escolheu o tema proposto que consiste em desenvolver uma máquina de busca de palavras, fica intrínseco ao conteúdo da disciplina como sendo um dos principais pilares do desenvolver deste trabalho acadêmico.

3.2 LINGUAGEM DE PROGRAMAÇÃO PARA WEB III

Desde a concepção dos programas básicos do projeto até sua finalização serão utilizados conceitos e técnicas aprendidas em ATP1 e ATP2 visto que o conhecimento destas duas disciplinas é imprescindível ao desenvolvimento do projeto, tais como programação básica em Java e Portugol que viabilizaram uma capacitação básica para outras linguagens da programação, além da própria utilização do JAVA no projeto. Portanto fica claro que outro grande pilar de sustentação no desenvolver deste trabalho é a programação em Java viabilizado pela disciplina ATP3.

3.3 LEGISLAÇÃO APLICADA À INFORMÁTICA

A partir da necessidade de se registrar qualquer produto criado, incluindo softwares, objetivando proteger os direitos de quem o criou e de evitar apropriações indevidas. A disciplina em questão se integra nas anteriores para este trabalho, neste 5º período, cedendo textos a serem utilizados e posteriormente objetivando o registro do software conforme orientação da mesma, caso o mesmo possa ser utilizado de forma comercial e público.

Page 7: Implementacao de Uma Maquina de Busca Com o Lucene

7

4-Conceitos Básicos 4.1-O que é uma máquina de busca

“Um motor de busca, motor de pesquisa ou máquina de busca é um

sistema de software projetado para encontrar informações armazenadas

em um sistema computacional a partir de palavras-chave indicadas pelo

utilizador, reduzindo o tempo necessário para encontrar

informações”.(< http://pt.wikipedia.org/wiki/Motor_de_busca>Set.2011)

De modo geral um software de busca consiste em buscar um conjunto de documentos, seja ele na web ou não. Uma Máquina de Busca é dividida em 3 partes:

1. Coleta e armazenamento de documentos 2. Indexação dos mesmos 3. Processamento de consultas.

4.2- Porque criar uma máquina de busca textual? A partir do momento que um usuário precise buscar em textos informações

específicas não só por títulos e/ou autor mas também por palavras ou frases , como por exemplo em artigos que geralmente são algo em torno de 1500 palavras, imagine que no banco de artigos a serem buscados há mais de um milhão de artigos cadastrados, o usuário poderá usar um bom framework de busca textual será o mais viável pois uar o banco de dados do operador não seria a solução mais eficaz.

4.3-Recuperação da Informação (RI)

A Recuperação da Informação é "a tarefa de encontrar documentos

relevantes a partir de um corpus ou conjunto de textos em resposta a uma

necessidade de informação de um usuário". ( )

Um dos modelos de Recuperação da Informação mais conhecido é o espaço

vetorial, em inglês: Vector Space Model . Este modelo é usado por grandes

máquinas de busca.Um grande exemplo é o GOOGLE

4.3.1 Histórico Os primórdios da recuperação da Informação ocorreu a aproximadamente quarenta (40) séculos atrás com os brâmanes e suas escritas sumérias, posteriormente na década de quarenta (40) no século XX foi estudada por Bush(1941) e Weaver (1949). Em 1951 Mooers criou o termo : “Recuperação da Informação”.

Page 8: Implementacao de Uma Maquina de Busca Com o Lucene

8

4.4-Termos utilizados para Máquina de Busca:

� Search Engine; � Ferramenta de Busca; � Mecanismo de Busca; � Buscador; � Motor de Busca; � SRI (Sistema de Recuperação da Informação);

4.5 Estrutura

Arquitetura de uma máquina de busca

Page 9: Implementacao de Uma Maquina de Busca Com o Lucene

9

Etapas:

Histórico:

1

1993

2

1993

3

1994

4

1994

5

1994

6

1995

7

1995

8

1995

9

1995

10

1995

11

1996

12

1997

13

2009

Page 10: Implementacao de Uma Maquina de Busca Com o Lucene

10

4.4-ETAPAS DE UMA MÁQUINA DE BUSCA:

4.1-COLETOR:

Indica quais os domínios a serem catalogados, os tipos de servidores a entrarem na coleta, os tipos de arquivos a serem buscados dentre outros.

Um modelo conhecido é o tipo Aranha onde a web pode ser caracterizada como um grafo direcionado onde cada URL é um vértice e os links entre elas são as arestas.

4.2-ARMAZENAMENTO: Consiste no armazenamento de páginas de diversos formatos: html, txt, doc,

pdf, dentre outros. Atualmente o texto das figuras também é indexado.

4.3-INDEXAÇÃO: Consiste no retorno das informações sobre as páginas, onde estas informações

deverão ser armazenadas de modo a serem utilizadas para responder a posteriores perguntas de usuários.Este processo pode variar de máquina de busca para máquinas de busca.

4.3.1-Características da indexação : Quando a indexação é feita de forma automática, pode variar em sofisticação a

fim de melhorar a precisão de resposta, assim os documentos s serem indexados, o serão por frequência de palavras e frases, atribuindo ou não pesos para as posições ondem aparecem as palavras. Como exemplo temos uma palavra no título da página com maior peso que uma palavra no texto. Outro exemplo “consiste na utilização de meta tags supracitadas também pode ser usada nesta fase.”

4.3.2-Velocidade de indexação : O processo de indexação utiliza-se de tempo. O site www. altavista. com.br

demora em torno de 6 semanas para que uma url achada pelo SPIDER (….) ser listada na base de dados indexada e ser encontrada, conforme Müller (1999) 4.4-CONSULTA:

Com os passos anteriores a máquina de busca é capaz de receber pedidos de busca. A partir de um pedido requerido a máquina de busca no índice entradas que agrupam, ou seja, casem com o pedido de busca e ordena as respostas pelo que determina ser mais importante.

4.4.1-Modelos Clássicos para Recuperação da Informação

• Modelo Booleano • Modelo Vetorial • Modelo Probabilístico

5-TIPOS DE MÁQUINAS DE BUSCA: 5.1-Buscadores Globais:

Este modelo busca documentos na rede e apresenta-o de forma aleatória, dependendo da quantidade de acesso ao site, dentre outros fatores. Um exemplo é o GOOGLE.

Page 11: Implementacao de Uma Maquina de Busca Com o Lucene

11

5.2-Buscadores Verticais: Este tipo realiza pesquisas especializadas, com base de dados

própria. Está relacionado à busca relativo á pagamento de mensalidade ou de um valor por clic. Exemplo: BuscaPé;

5.3-Guias Locais:

Este tipo está relacionado a buscadores locais e regionais e as informações estão relacionadas a endereços de empresas e prestadores de serviço. Geralmente são cadastros de publicações pagas. É indicado para empresas que procuram oferecer produtos e serviços em uma região exemplo: AcheCerto;

5.4-Guias de Busca Locais:

São buscadores de abrangência nacional que lista as empresas e prestadores de serviços próximas ao endereço do internauta a partir de um texto digitado. A proximidade é avaliada normalmente pelo cep, Donavera.com, ou por coordenadas de GPs.”(fonte)

5.5-Diretórios de Web Sites:

Este tipo de buscador é organizado por categorias e subcategorias, sua finalidade é permitir ao usuário encontrar rapidamente sites que desejar, buscando por categorias, e não por palavras-chave , são índices de sites.Ex: Open Directory Project;

6-O SISTEMA DE RECUPERAÇÃO DA INFORMAÇÃO (SRI)

O SRI “interpreta” o conteúdo das informações encontradas nos documentos de uma coleção e vai ordená-los de acordo com um grau de relevância para o usuário. Relevância: A recuperação de todos documentos relevantes a consulta do usuário é o objetivo do SRI e o menor número possível de documentos não relevantes. Revocação (Recall):Consiste em medidas comuns que avaliam a qualidade de um sistema de busca e recuperação da informação, juntamente com a precisão. A revocação mede a proporção de documentos relevantes que foram retornados como resultados de uma consulta feita pelo usuário. Precisão: esta mede a quantidade de documentos relevantes recuperados.

A eficiência da indexação de um documento e a eficiência da revocação e precisão são influenciados por dois fatores importantes: Exaustividade: “Define o número de diferentes conceitos (tópicos) que estão indexados;” Especificidade: “Define o grau de precisão da linguagem de indexação em descrever um dado documento.”

O objetivo geral deste sistema de informação é minimizar o overhead para localização da informação para o usuário. Para isso deve-se observar os seguintes itens:

� tempo para geração da pergunta ; � tempo para execução da pergunta; � tempo para buscar os resultados; � tempo para organização da resposta para ser mostrada ao usuário; � tempo perdido para encontrar o resultado com leituras de documentos não

relevantes;

Page 12: Implementacao de Uma Maquina de Busca Com o Lucene

12

Indexação: Os termos de indexação são palavras-chaves de documentos que representam uma coleção destes documentos. Estas palavras podem ser extraídas dos documentos de forma automática ou selecionadas por especialistas, gerando de qualquer modo uma visão lógica dos documentos.

Arquivo invertido: O Arquivo Invertido consiste em um conjunto de números de documentos contendo o termo, ou seja, é uma lista invertida que aplica-se ao tipo de índice que aponta os documentos que contém os vários termos de um texto, assim um arquivo invertido mostra para cada termo do vocabulário uma lista invertida.

São muito utilizados, devido eficiência nas buscas e possibilidade de compressão, mas necessitam uma estrutura auxiliar: o vocabulário ou léxico, uma lista de todos os termos distintos que ocorrem no texto.

7-O LUCENE O LUCENE consiste em um Framework para busca textual feito em java, apresenta características importantes como a integração com o Hadoop (outro framework para computação distribuída que possui um MapReduce e um sistema de arquivos distribuídos-HDFS) .

Criado por Doug Cutting em 2000, o Lucene é uma das mais famosas e mais usadas bibliotecas para indexação e consulta de textos, disponível em código aberto. Sob o domínio da Apache Foundation, a biblioteca, escrita em java, pode ser utilizada em qualquer aplicativo J2SE ou J2EE, de código aberto ou não. Outras linguagens como Delphi, Perl, C#, C++, Python, Ruby , PHP e JAVA, devem usar os ports do Lucene para as referidas linguagens. (<http://vitorpamplona.com/wiki/Introdu%C3%A7%C3% A3o%20ao%20Apache%20Lucene>)

7.1-Como o LUCENE funciona?

Na primeira fase consiste na indexação do documento, onde o documento é analisado por um ANALIZER que já retira as STOPWORDS para ,a posteriori, ser indexado. Veja abaixo o código: Set stopWords = new HashSet(); stopWords.add("the"); stopWords.add("it"); stopWords.add("is"); IndexWriter writer = new IndexWriter(FSDirectory.open(INDEX_DIR), new StandardAnalyzer(Version.LUCENE_CURRENT,stopWords), false,IndexWriter.MaxFieldLength.LIMITED); O Lucene permite a criação de um índice usando o IndexWriter, que permite dizer onde será, ou está, o diretório dos índices, qual analizador será utilizado, se irá criar o índice e a quantidade máxima de campos.Para indexar os documentos o indexador necessita que haja documentos a serem indexados. Observe o código abaixo: Document doc = new Document(); doc.add(new Field("nomedocampo", "valores a serem guardados",

Page 13: Implementacao de Uma Maquina de Busca Com o Lucene

13

Field.Store.YES, Field.Index.NOT_ANALYZED)); doc.add(new Field("camp1","valores a serem analisados tokenizados",Field.Store.YES, Field.Index.toIndex(true, true))); writer.addDocument(doc); Visto que o objetivo final de todo processo de busca textual é mesmo a busca em si. String valueToBeSearched = "red"; String index = "indexDir"; //dirotorio base do indice IndexReader reader = IndexReader.open(FSDirectory.open(new File(index)), true); //indexador Searcher searcher = new IndexSearcher(reader); //pesquisador QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, field, analyzer); //transoformador do texto em uma query Query query = parser.parse(valueToBeSearched); //a consulta (query) em si TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, false); //os melhores resultados searcher.search(query, collector); ScoreDoc[] hits = collector.topDocs().scoreDocs; //o conjunto de melhores documentos para a consulta int maximo = hits.length; Document doc = searcher.doc(hits[index].doc); String valor = doc.get("nomeDoCampo");

7.2 Recursos na busca de documentos No Lucene Quando se faz uma pesquisa por documentos pode-se utilizar de alguns operadores (+, -, AND, NOT, OR, * e etc.) em conjunto com o termo pesquisado ou apenas pesquisar uma frase completa. Exemplo : termo Consequência: pesquisará a palavra "termo" nos documentos indexados. Exemplo : termo OR palavra ( == termo palavra) Consequência: pesquisará "termo" ou "palavra" nos documentos indexados. Exemplo : +termo +palavra ( == termo AND palavra) Consequência: pesquisará "termo" e "palavra" nos documentos indexados. Exemplo : campo:termo Consequência: pesquisará "termo" no campo "campo" nos documentos indexados. Exemplo : +homer +simpsons -house Consequência: pesquisará documentos que contenham homer e simpsons e não tenha

house. Exemplo : "termo exato" Consequência: pesquisará documentos que contenham exatamente "termo exato". Exemplo : java* Consequência: pesquisará documentos que contenham palavras que começem com java

(javadb, javanet...).

Page 14: Implementacao de Uma Maquina de Busca Com o Lucene

14

Exemplo : java~ Consequência: pesquisará documentos que contenham palavras similares a java como por

ex. lava, jaba... (fonte:.....) Sobre o LUCENE pode-se obter mais informações no ANEXO I

8-MB TEXT

A Máquina de Busca Textual que será criada “MBText” tem por objetivo indexar

um conjunto de arquivos textuais a fim de localizar palavras e trechos dos mesmos. Este sistema poderá, também, ser anexado em outros softwares a serem criados

em sistemas de empresas e sites. Portanto, outro objetivo se mostra intrínseco ao desenvolver do trabalho em si, o

desenvolver de um produto, não um produto qualquer mas um software, que possa entrar no mercado com condições de competir no mercado , se complementado e incorporado a sites e sistemas podendo o mesmo ser modificado, melhorado para melhor se adequar à necessidade proposta.

A desenvolver

Page 15: Implementacao de Uma Maquina de Busca Com o Lucene

15

9-CONCLUSÃO

ConclusãoO Lucene, uma biblioteca de software livre muito conhecida a partir do Apache, fornece recursos de indexação e de procura poderosos para os aplicativos. Ele fornece uma API simples e fácil de usar que requer entendimento mínimo dos componentes internos de indexação e procura. Neste artigo, você aprendeu sobre a arquitetura Lucene e suas APIs principais.

O Lucene desenvolveu vários aplicativos de procura utilizados por vários Web sites e organizações famosos. Ele suporta várias outras linguagens de programação. O Lucene possui uma grande e ativa comunidade técnica do usuário. Se você está a procura de uma biblioteca de procura de software livre de alto desempenho, escalável e fácil de usar, o Apache Lucene é uma ótima escolha.

A partir da pesquisa bibliográfica do tema proposto e da aprovação pelo professor coordenador do interdisciplinar para este grupo em questão foi desenvolvido este trabalho. Assim foi dada ênfase nas disciplinas de Linguagem e programação para a Web III, Máquina de Busca e Legislação Aplicada a Informática, visto que não há um tempo real (horário específico) para o desenvolvimento junto aos orientadores bem como o trabalho diurno dos alunos, juntamente com o excesso de trabalhos extraclasse dificultaram um melhor aproveitamento do tempo para viabilizar o desenvolvimento do trabalho/projeto de forma mais criteriosa e com uma abordagem de forma a abranger uma gama maior de conteúdo interdisciplinar . Portanto espera-se dar prosseguimento ao projeto mesmo após o curso afim de vê-lo aperfeiçoado, corrigido e incrementado para que possa , em futuro próximo inserido no mercado de forma competitiva e atrativa aos olhos de seus usuários.

Page 16: Implementacao de Uma Maquina de Busca Com o Lucene

16

10-BIBLIOGRAFIA

UNIPAC,Universidade Presidente Antônio Carlos. Manual de Orientação do Trabalho Interdisciplinar de Conclusão de Módulo.Unipac.2ºsemestre2011. MANZANO, José A.N.Garcia.JÚNIOR, Roberto A. da Costa.JAVA2 Programação de Computadores.Guia Básico de Introdução, Orientação e Desenvolvimento.São Paulo: Erica. .2006.368p. FREEMAN,Elizabeth. FREEMAN,Erick . Use a Cabeça HTML com CSS e XHTML

Rio de Janeiro: AltaBooks. 2008. 2ªed 616p(Tradução Betina Macêdo). SIERRA, Kato.BATES, Bert.Java.Use a Cabeça!.Rio de Janeiro: AltaBooks. 2010.2ªed 488p; SOUZA, Emmanuel Cássio Oliveira. Criando textos segundo as normas da ABNT. Scelisual, 2005. 41 p MOREIRA.Leandro.Lucene,Um Motor de Busca Textual <http://archsofty.blogspot. com /2009/12 /tutorial-apache-lucene-300-motor-de.html>Acesso em:26/09/11 PAMPLONA,Vitor.Introdução ao Apache Lucene <http://vitorpamplona.com> Acesso em:26/9/11 SONAWANE,Amol.Usando o Apache Lucene Para Procura de Texto <http://www.ibm.com/developerworks/br/java/library/os-apache-lucenesearch/index.html> Acesso em:29/9/11

Lucene <http://www.ibm.com/developerworks/br/java/library/os-apache-lucenesearch/index.html> Acesso em: 28/9/11 Introdução ao Apache Lucene <http://vitorpamplona.com/wiki/Introdu%C3% A7%C3%A3o%20ao%20Apache%20Lucene>Acesso em :01/10/11 Poderão ser acrescentados mais referências

ANEXO I

Page 17: Implementacao de Uma Maquina de Busca Com o Lucene

17

LUCENE:

Fonte:http://www.ibm.com/developerworks/br/java/library/os-apachelucenesearch/ index.html

Introdução

O Lucene é uma biblioteca de mecanismo de procura de texto altamente escalável e de software livre a partir do Apache Software Foundation. Você pode usar o Lucene em aplicativos comerciais e de software livre. As APIs poderosas do Lucene focam principalmente na indexação e na procura de texto. Elas podem ser usadas para criar recursos de procura para aplicativos, como clientes de e-mail, listas de correspondências, procuras da Web, procuras de banco de dados, etc. Web sites como Wikipedia, TheServerSide, jGuru e LinkedIn foram desenvolvidos com o Lucene.

O Lucene também fornece recursos de procura para o Eclipse IDE, Nutch (o famoso recurso de procura da Web de software livre) e empresas como IBM®, AOL e Hewlett-Packard. O Lucene suporta várias outras linguagens de programação, dentre elas Perl, Python, C++ e .NET. A partir de 30 de julho de 2009, a versão mais recente do Lucene na ™ linguagem de programação Java é V2.4.1.

O Lucene possui vários recursos. Ele:

• Possui algoritmos de procura poderosos, precisos e eficientes. • Calcula uma pontuação para cada documento que corresponda a uma

determinada consulta e retorna a maioria dos documentos relevantes classificados por essas pontuações.

• Suporta vários tipos de consultas poderosos, como Phrase Query, Wildcard Query, Range Query, Fuzzy Query, Boolean Query e outros.

• Suporta a análise de expressões de consulta completas digitadas pelo usuário. • Permite que os usuários estendam o comportamento da procura usando

classificação, filtragem e análise de expressão de consulta. • Usa um mecanismo de bloqueio baseado em arquivo para impedir modificações

de índices simultâneos. • Permite a procura e a indexação simultaneamente.

Voltar para parte superior

Construindo Aplicativos Usando o Lucene

Como mostra a Figura 1, a criação de um aplicativo de procura cheio de recursos usando o Lucene envolve, primeiramente, a indexação de dados, a procura de dados e a exibição de resultados de procura.

Page 18: Implementacao de Uma Maquina de Busca Com o Lucene

18

Figura 1. Etapas para criar aplicativos usando o Lucene

Esse artigo usa fragmentos de código a partir de um aplicativo de amostra desenvolvido com a tecnologia Java usando o Lucene V2.4.1. O aplicativo de exemplo indexa um conjunto de documentos de e-mail armazenados nos arquivos de propriedades e mostra como usar as APIs de consulta do Lucene para procurar um índice. Com esse exemplo, você também pode se familiarizar com as operações básicas de índice.

Indexando Dados

O Lucene permite indexar quaisquer dados disponíveis no formato textual. O Lucene pode ser usado quase com qualquer origem de dados contanto que as informações textuais possam ser extraídas dela. Você pode usar o Lucene para indexar e procurar dados armazenados em documentos HTML, Microsoft® Word, arquivos PDF e outros. A primeira etapa na indexação de dados é disponibilizá-los em um formato de texto simples. Faça isso usando os analisadores e conversores de dados customizados.

O Processo de Indexação

A Indexação é um processo de converter os dados de texto em um formato que facilita a procura rápida. Uma analogia simples é um índice que seria localizado no final de um manual: Esse índice aponta para o local dos tópicos que aparecem no manual.

O Lucene armazena os dados de entrada em uma estrutura de dados chamada de índice invertido , que é armazenado no sistema de arquivos ou na memória como um conjunto de arquivos de índice.A maioria dos mecanismos de procura da Web usa um índice invertido. Ele permite que os usuários executem procuras rápidas por palavras-chave e localizem os documentos que correspondem a uma determinada consulta. Antes que os dados de texto sejam incluídos no índice, eles são processados por um analisador (usando um processo de análise).

Page 19: Implementacao de Uma Maquina de Busca Com o Lucene

19

Análise

Análise é a conversão dos dados de texto em uma unidade de procura fundamental, chamada de termo. Durante a análise, os dados de texto passam por várias operações: extração das palavras, remoção de palavras comuns, ignorar pontuação, redução de palavras para o formato de raiz, alteração das palavras para minúsculas, etc. A análise acontece imediatamente antes de analisar a indexação e a consulta. A análise converte os dados de texto em tokens e esses tokens são incluídos como termos no índice do Lucene.

O Lucene é fornecido com vários analisadores integrados, como o Simple Analyzer, o StandardAnalyzer, StopAnalyzer, SnowballAnalyzer, e outros. Eles diferem na maneira pela qual tokenizam o texto e aplicam os filtros. Conforme a análise remove as palavras antes de indexar, ela diminui o tamanho do índice, mas isso poderá ter um efeito negativo na precisão do processamento da consulta. É possível ter maior controle sobre o processo de análise ao criar analisadores customizados usando os blocos de construção básicos fornecidos pelo Lucene. A Tabela 1 mostra os analisadores integrados e como eles podem processar dados.

Tabela 1. Analisadores Integrados do Lucene Analisador Operações realizadas nos dados de texto WhitespaceAnalyzerDivide os tokens em espaço em branco

SimpleAnalyzer Divide o texto em caracteres que não sejam letras e coloca o texto em minúsculo

StopAnalyzer Remove as palavras irrelevantes (desnecessárias para procura) e coloca o texto em minúscula

StandardAnalyzer

Tokeniza o texto com base em uma gramática sofisticada que reconhece endereços de e-mail, acrônimos, caracteres chinês, japonês e coreano, caracteres alfanuméricos, e outrosColoca o texto em minúsculo e remove palavras comuns.

Classes de Indexação de Núcleo

Diretório Uma classe abstrata que representa o local onde os arquivos de índice são armazenados. Há duas subclasses principais normalmente usadas:

• FSDirectory — Uma implementação do Diretório que armazena índices no sistema de arquivos real.Isso é útil para grandes índices.

• RAMDirectory — Uma implementação que armazena todos os índices na memória. Isso é ideal para índices menores que podem ser completamente carregados na memória e destruídos quando o aplicativo encerrar. Conforme o índice é mantido na me, ele é comparadamente mais rápido.

Analisador Conforme já falado, os analisadores são responsáveis por processar os

dados de texto e convertê-los em tokens armazenados no índice. IndexWriter aceita um analisador usado para tokenizar os dados antes de serem indexados. Para indexar o texto corretamente, use um analisador que seja apropriado para o idioma do texto que precisa ser indexado.

Page 20: Implementacao de Uma Maquina de Busca Com o Lucene

20

Os analisadores padrão funcionam bem com o idioma inglês. Há vários outros analisadores no sandox Lucene, dentre eles para o chinês, japonês e coreano.

IndexDeletionPolicy Uma interface usada para implementar uma política para customizar a

exclusão de consolidações obsoletas do diretório de índice. A política de exclusão padrão é KeepOnlyLastCommitDeletionPolicy, que mantém apenas as consolidações mais recentes e remove imediatamente todas as consolidações anteriores depois que a nova consolidação for feita.

IndexWriter Um classe que cria ou mantém um índice. Seu construtor aceita um

booleano que determina se um novo índice é criado ou se um índice existente é aberto. Ele fornece métodos para incluir, excluir ou atualizar documentos no índice.

As alterações feitas no índice são inicialmente armazenadas em buffer na memória e periodicamente esvaziadas para o diretório de índice.IndexWriter Expõe vários campos que controlam como os índices são armazenados em buffer na memória e gravados no disco. As alterações feitas no índice não são visíveis no IndexReader , a menos que o método de consolidação ou de fechamento do IndexWriter seja chamado. IndexWriter cria um arquivo de bloqueio para o diretório para impedir distorção de índice devido a atualizações de índice simultâneas. IndexWriter permite que os usuários especifiquem uma política de exclusão de índice opcional.

Listagem 1. Usando o Lucene IndexWriter

//Criar instância do Diretório onde os arquivos de índice serão armazenados Directory fsDirectory = FSDirectory.getDirectory(indexDirectory); /* Criar instância do analisador, que será usada para tokenizar os dados de entrada */ Analyzer standardAnalyzer = new StandardAnalyzer(); //Criar um novo índice booleano create = true; //Criar a instância da política de exclusão IndexDeletionPolicy deletionPolicy = new KeepOnlyLastCommitDeletionPolicy(); indexWriter =new IndexWriter(fsDirectory,standardAnalyzer,create, deletionPolicy,IndexWriter.MaxFieldLength.UNLIMITED);

Incluindo Dados em um Índice

Há duas classes envolvidas na inclusão de dados de texto no índice.

O Campo representa uma parte dos dados consultados ou recuperados na procura. A classe Campo engloba o nome de campo e seu valor. O Lucene fornece as opções para especificar se um campo precisa ser indexado ou analisado e se o valor precisa ser armazenado. Essas opções podem ser transmitidas ao criar uma instância de campo. A tabela abaixo mostra os detalhes das opções de metadados de Campo .

Page 21: Implementacao de Uma Maquina de Busca Com o Lucene

21

Tabela 2. Detalhes das opções de metadados de Campo Opção Descrição

Field.Store.Yes Usado para armazenar o valor dos campos. Ideal para campos exibidos com o caminho de arquivo de resultados de procura — e com a URL, por exemplo.

Field.Store.No O valor de campo não é armazenado — o corpo da mensagem de e-mail, por exemplo.

Field.Index.No Ideal para campos pouco procurados— usados com os campos armazenados, como por exemplo, caminho de arquivo.

Field.Index.ANALYZED Usado para campos indexados e analisados — o corpo e o assunto da mensagem de e-mail, por exemplo.

Field.Index.NOT_ANALYZEDUsado para campos indexados mas não analisados Ele preserva o valor original do campo em sua totalidade —datas e nomes pessoais, por exemplo.

E um Documento é uma coleta de campos. O Lucene também suporta a impulsão de documentos e campos, que é um recurso útil quando quiser dar importância a alguns dos dados indexados. Indexar um arquivo de texto envolve agrupar os dados de texto em campos, criar um documento, preenchê-lo com campos e incluir o documento no índice usando IndexWriter.

A Listagem 2 mostra um exemplo da inclusão de dados em um índice.

Listagem 2. Incluindo dados em um índice

/*Etapa 1. Preparar dados para indexação. Extrair dados. */ String sender = properties.getProperty("sender"); String date = properties.getProperty("date"); String subject = properties.getProperty("subject"); String message = properties.getProperty("message"); String emaildoc = file.getAbsolutePath(); /* Etapa 2. Agrupar dados nos Campos e incluí-los em um Documento */ Field senderField = new Field("sender",sender,Field.Store.YES,Field.Index.NOT_ANALYZED); Field emaildatefield = new Field("date",date,Field.Store.NO,Field.Index.NOT_ANALYZED); Field subjectField = new Field("subject",subject,Field.Store.YES,Field.Index.ANALYZED); Field messagefield = new Field("message",message,Field.Store.NO,Field.Index.ANALYZED); Field emailDocField = new Field("emailDoc",emaildoc,Field.Store.YES, Field.Index.NO);

Page 22: Implementacao de Uma Maquina de Busca Com o Lucene

22

Document doc = new Document(); // Incluir esses campos em um Documento Lucene doc.add(senderField); doc.add(emaildatefield); doc.add(subjectField); doc.add(messagefield); doc.add(emailDocField); //Etapa 3: Incluir esse documento no Índice Lucene. indexWriter.addDocument(doc);

Procurando Dados Indexados

A procura é o processo de buscar palavras no índice e de localizar os documentos que contêm essas palavras. A criação de recursos de procura usando a API de procura do Lucene é um processo direto e fácil. Essa seção aborda as classes principais a partir da API de procura do Lucene.

Procurador

Procurador é uma classe base abstrata que possui vários métodos de procura sobrecarregadas. IndexSearcher é uma subclasse normalmente utilizada que permite procurar índices armazenados em um determinado diretório. O método Procurar retorna uma coleta ordenada de documentos classificados pelas pontuações computadas. O Lucene calcula uma pontuação de cada documento que corresponde a uma determinada consulta. IndexSearcher é um thread-safe, ou seja, uma instância única que pode ser usada por vários encadeamentos simultaneamente.

Termo

Termo é a unidade mais fundamental de procura. Ele é composto de dois elementos: o texto da palavra e o nome do campo no qual o texto ocorre. Os objetos do termo são envolvidos na indexação, mas são criados pelos componentes internos do Lucene.

Consulta e Subclasses

Consulta é uma classe base abstrata para procuras. Procurar por uma palavra ou frase especificada envolve agrupá-la em um termo, incluir os termos em um objeto de consulta e transmitir esse objeto de consulta para os métodos de procura do Index Searcher.

O Lucene é fornecido com vários tipos de implementações de consulta concretas, como TermQuery, BooleanQuery, PhraseQuery, PrefixQuery, RangeQuery, MultiTermQuery, FilteredQuery, SpanQuery, etc. A seção abaixo descreve as classe de consulta primárias a partir da API de consulta do Lucene.

TermQuery O tipo de consulta mais básico para procurar um índice.TermQuery pode ser

construído usando um termo único. O valor do termo deve fazer distinção entre maiúsculas e minúsculas, mas isso não é totalmente verdade. É importante notar que os

Page 23: Implementacao de Uma Maquina de Busca Com o Lucene

23

termos transmitidos para procura devem ser consistentes com os termos produzidos pela análise de documentos, porque os analisadores executam muitas operações no texto original antes de criar um índice.

Por exemplo, considere o assunto de e-mail "Aberturas de tarefa para Profissionais Java em Bangalore." Suponha que você indexou isso usando o StandardAnalyzer. Agora, se procurarmos por "Java" usando o TermQuery, nada será retornado já que o texto foi normalizado e colocado em letras minúsculas pelo StandardAnalyzer. Se procurarmos pela palavra em letras minúsculas "java," todos os e-mails que contiverem essa palavra no campo de assunto serão retornados.

Listagem 3. Procurando Usando o TermQuery

//Procurar e-mail com a palavra "java" no campo de assunto Searcher indexSearcher = new IndexSearcher(indexDirectory); Term term = new Term("subject","java"); Query termQuery = new TermQuery(term); TopDocs topDocs = indexSearcher.search(termQuery,10);

RangeQuery

Você pode procurar em um intervalo usando o RangeQuery. Todos os termos

são organizados de maneira lexicográfica no índice. O RangeQuery do Lucene permite que os usuários procurem termos dentro de um intervalo.O intervalo pode ser especificado usando um termo de início e um termo de encerramento, que pode ser incluído ou excluído.

Listagem 4. Procurando em um Intervalo

/* RangeQuery example:Search mails from 01/06/2009 to 6/06/2009 both inclusive */ Term begin = new Term("date","20090601"); Term end = new Term("date","20090606"); Query query = new RangeQuery(begin, end, true);

PrefixQuery Você pode procurar usando uma palavra prefixada com o PrefixQuery, que é

usado para contruir uma consulta que corresponda aos documentos que contêm os termos que iniciam com um prefixo de palavra especificada.

Listagem 5. Procurando Usando o PrefixQuery

//Procurar e-mails que possuem o campo remetente prefixado pela palavra 'job' PrefixQuery prefixQuery = new PrefixQuery(new Term("sender","job")); PrefixQuery query = new PrefixQuery(new Term("sender","job"));

Page 24: Implementacao de Uma Maquina de Busca Com o Lucene

24

BooleanQuery Você pode construir consultas poderosos ao combinar qualquer número de

objetos de consulta usando o BooleanQuery. Ele usa o query e uma cláusula associada a uma consulta que indica se uma consulta pode ocorrer, deve ocorrer ou não deve ocorrer. Em um BooleanQuery, o número máximo de cláusulas é restrito a 1.024, por padrão. É possível configurar o máximo de classes ao chamar o método setMaxClauseCount .

Listagem 6. Procurando Usando o BooleanQuery

// Procurar e-mails que possuem 'java' e 'bangalore' no campo de assunto Query query1 = new TermQuery(new Term("subject","java")); Query query2 = new TermQuery(new Term("subject","bangalore")); BooleanQuery query = new BooleanQuery(); query.add(query1,BooleanClause.Occur.MUST); query.add(query2,BooleanClause.Occur.MUST);

PhraseQuery

Você pode procurar por uma frase usando o PhraseQuery. Um PhraseQuery corresponde aos documentos que contêm uma determinada sequência de termos. PhraseQuery usa informações posicionais do termo que são armazenadas em um índice. A distância entre os termos que são considerados para serem correspondidos é chamada de slop. Por padrão, o valor do slop é zero e pode ser configurado ao chamar o método setSlop . PhraseQuery também suporta várias frases de termos.

Listagem 7. Procurando Usando o PhraseQuery

/* Exemplo de PhraseQuery: Procurar e-mails que possuem a frase 'job opening j2ee' no campo de assunto.*/ PhraseQuery query = new PhraseQuery(); query.setSlop(1); query.add(new Term("subject","job")); query.add(new Term("subject","opening")); query.add(new Term("subject","j2ee"));

WildcardQuery Um WildcardQuery implementa uma consulta com caractere curinga, podendo

fazer procuras como arch* (permitindo localizar documentos que contém architect, architecture, etc.). Dois caracteres curingas padrão são usados:

* para zero ou mais

? para um ou mais

Pode haver uma queda de desempenho se você tentar procurar usando um padrão no início de uma consulta com caractere curinga, já que todos os termos no índice serão consultados para localizar documentos correspondentes.

Page 25: Implementacao de Uma Maquina de Busca Com o Lucene

25

Listagem 8. Procurando Usando WildcardQuery

//Procurar por 'arch*' para localizar mensagens de e-mail que possuem a palavra 'architect' no campo de assunto./ Query query = new WildcardQuery(new Term("subject","arch*"));

FuzzyQuery

Você pode procurar por termos semelhantes com o FuzzyQuery, que corresponde às palavras que são semelhantes a sua palavra especificada. A medida de semelhança baseia-se no algoritmo Levenshtein (editar distância). Na Listagem 9, FuzzyQuery é usado para localizar uma correspondência próxima de uma palavra que foi digitada incorretamente, como "admnistrtor," embora essa palavra não tenha sido indexada.

Listagem 9. Procurando Usando o FuzzyQuery

/* Procurar por e-mails que possuem palavras semelhantes a 'admnistrdor' no campo de assunto. Note que digitamos incorretamente admnistrtor aqui.*/ Query query = new FuzzyQuery(new Term("subject", "admnistrtor"));

QueryParser

QueryParser é útil para analisar cadeias de consultas inseridas pelo usuário. Ele pode ser usado para analisar expressões de consultas inseridas pelo usuário em um objeto de consulta do Lucene, que pode ser transmitido para o método de procura do IndexSearcher.Ele pode analisar expressões de consultas completas. QueryParser converte internamente uma cadeia de consulta inserida pelo usuário em uma das subclasses de consulta concretas. É necessário escapar caracteres especiais, como *, ? com uma barra invertida (\). Você pode construir consultas booleanas textualmente usando os operadores AND, OR e NOT.

Listagem 10. Procurando por expressão de consulta inserida pelo usuário

QueryParser queryParser = new QueryParser("subject",new StandardAnalyzer()); // Procurar e-mails que contêm as palavras 'job openings' and '.net' and 'pune' Query query = queryParser.parse("job openings AND .net AND pune");

Exibindo Resultados de Procura

IndexSearcher retorna uma matriz de referências nos resultados de procura classificados, como documentos que correspondem a uma determinada consulta. Você pode decidir o número dos principais resultados de procura que precisam ser recuperados ao especificá-lo no método de procura do IndexSearcher.A paginação customizada pode ser criada sobre isso. Você pode incluir um aplicativo da Web customizado ou um aplicativo de desktop para exibir os resultados de procura. As classes primárias envolvidas na recuperação dos resultados de procura são ScoreDoc e TopDocs.

Page 26: Implementacao de Uma Maquina de Busca Com o Lucene

26

ScoreDoc

Um ponteiro simples para um documento contido nos resultados de procura. Isso engloba a posição de um documento no índice e a pontuação calculada pelo Lucene. TopDocs

Engloba o número total de resultados de procura e uma matriz de ScoreDoc.O fragmento de código abaixo mostra como recuperar documentos contidos nos resultados de procura. Listagem 11. Exibindo Resultados de Procura /* O primeiro parâmetro é a consulta a ser executada e o segundo parâmetro indica que nenhum dos resultados de procura será buscado */ TopDocs topDocs = indexSearcher.search(query,20); System.out.println("Total hits "+topDocs.totalHits); // Obter uma matriz de referências aos documentos correspondidos ScoreDoc[] scoreDosArray = topDocs.scoreDocs; for(ScoreDoc scoredoc: scoreDosArray){ //Recuperar o documento correspondido e mostrar detalhes relevantes Document doc = indexSearcher.doc(scoredoc.doc); System.out.println("\nSender: "+doc.getField("sender").stringValue()); System.out.println("Subject: "+doc.getField("subject").stringValue()); System.out.println("Email file location: " +doc.getField("emailDoc").stringValue()); } Operações Básicas de Índices

As operações básicas de índice incluem remover e impulsionar documentos.

Removendo Documentos de um Índice

Geralmente é necessário atualizar os aplicativos com os dados mais recentes e remover dados antigos. Por exemplo, no caso de mecanismos de procura da Web, o índice precisa ser atualizado regularmente conforme novas páginas da Web são incluídas e as páginas da Web não-existentes precisam ser removidas. O Lucene fornece a interface IndexReader que permite executar essas operações em um índice.

IndexReader é uma classe abstrata que fornece vários métodos para acessar o índice. O Lucene refere internamente os documentos com números de documentos que podem ser alterados conforme os documentos são incluídos ou excluídos do índice. O número do documento é usado para acessar um documento no índice. IndexReader não pode ser usado para atualizar índices em um diretório para o qual o IndexWriter já está aberto. IndexReader sempre procura pela captura instantânea do índice quando ele estiver aberto. Quaisquer alterações no índice não estarão visíveis até o IndexReader ser reaberto. É importante que os aplicativos que usam o Lucene reabram os IndexReaderpara ver as atualizações de índice mais recentes.

Page 27: Implementacao de Uma Maquina de Busca Com o Lucene

27

Listagem 12. Excluindo Documentos do Índice // Excluir todos os e-mails do índice recebidos em maio de 2009. IndexReader indexReader = IndexReader.open(indexDirectory); indexReader.deleteDocuments(new Term("month","05")); //Fechar os arquivos de índice associados e salvar as exclusões no disco indexReader.close(); Impulsionando Documentos e Campos

Ás vezes você pode querer dar mais importância a alguns dos dados indexados. Você pode querer fazer isso ao configurar um fator de impulso para um documento ou campo.Por padrão, todos os documentos e campos possuem o mesmo fator de impulso padrão de 1.0.

Listagem 13. Campos de Impulsão if(subject.toLowerCase().indexOf("pune") != -1){ // Exibir resultados de procura que contém pune no primeiro assunto ao configurar o fator de impulso subjectField.setBoost(2.2F); } // Exibir resultados de procura que contêm 'job' no endereço de e-mail do remetente if(sender.toLowerCase().indexOf("job")!=-1){ luceneDocument.setBoost(2.1F); }

Estendendo a Procura

O Lucene fornece um recurso avançado chamado classificação. Você pode classificar os resultados da procura por campos que indicam a posição relativa dos documentos no índice. O campo usado para classificação deve ser indexado, mas não tokenizado. Há quatro tipos possíveis de valores de termos que podem ser colocados nos campos de classificação: integers, longs, floats ou strings.

Os resultados da procura também podem ser classificados pela ordem do índice. O Lucene classifica os resultados ao diminuir a relevância, como a pontuação calculada, por padrão. A ordem de classificação também pode ser alterada.

Listagem 14. Classificando Resultados de Procura /* Procurar e-mails que possuem a palavra 'job' no assunto e retornar resultados classificados pelo e-mail do remetente em ordem decrescente. */ SortField sortField = new SortField("sender", true); Sort sortBySender = new Sort(sortField); WildcardQuery query = new WildcardQuery(new Term("subject","job*")); TopFieldDocs topFieldDocs = indexSearcher.search(query,null,20,sortBySender); //Classificar por ordem de índice topFieldDocs = indexSearcher.search(query,null,20,Sort.INDEXORDER);

Page 28: Implementacao de Uma Maquina de Busca Com o Lucene

28

Filtragem é um processo que restringe o espaço de procura e permite que apenas um subconjunto de documentos seja considerado para as ocorrências de procura. Você pode usar esse recurso para implementar os resultados de procura dentro de procura ou para implementar a segurança sobre os resultados de procura. O Lucene é fornecido com vários filtros integrados, como BooleanFilter, CachingWrapperFilter, ChainedFilter, DuplicateFilter, PrefixFilter, QueryWrapperFilter, RangeFilter, RemoteCaching WrapperFilter, SpanFilter, etc. Filtro pode ser transmitido para o método de procura do IndexSearcherpara filtrar documentos que correspondem aos critérios de filtragem.

Listagem 15. Filtrando Resultados de Procura /*Filtrar os resultados para mostrar apenas os e-mails que possuem o campo do remetente prefixado com 'jobs' */ Term prefix = new Term("sender","jobs"); Filter prefixFilter = new PrefixFilter(prefix); WildcardQuery query = new WildcardQuery(new Term("subject","job*")); indexSearcher.search(query,prefixFilter,20);

Page 29: Implementacao de Uma Maquina de Busca Com o Lucene

29

Page 30: Implementacao de Uma Maquina de Busca Com o Lucene

30

ANEXO II

Introdução ao Apache Lucene

Criado por Doug Cutting em 2000, o Lucene é uma das mais famosas e mais usadas bibliotecas para indexação e consulta de textos, disponível em código aberto. Sob o domínio da Apache Foundation, a biblioteca, escrita em java, pode ser utilizada em qualquer aplicativo J2SE ou J2EE, de código aberto ou não. Outras linguagens como Delphi, Perl, C#, C++, Python, Ruby , PHP e JAVA, devem usar os ports do Lucene para as referidas linguagens.

A biblioteca é composta por duas etapas principais: indexação e pesquisa (Figura 3.1). A indexação processa os dados originais gerando uma estrutura de dados inter-relacionada eficiente para a pesquisa baseada em palavras-chave. A pesquisa, por sua vez, consulta o índice pelas palavras digitadas em uma consulta e organiza os resultados pela similaridade do texto com a consulta.

Figura 3.1: Arquitetura do Apache Lucene. Imagem do Lucene in Action 2004.

O Lucene oferece um agradável nível de abstração para um conjunto poderoso de técnicas baseadas no modelo Vetorial e Booleano. O desenvolvedor não precisa conhecer rotinas e algoritmos de indexação, nem de consulta. Basta utilizá-los através da API da biblioteca. Apesar da facilidade de uso, o Lucene não implementa um webcrawler ou parsers de HTML / XML. Este processamento, se necessário, deve ser feito pela aplicação e repassado à biblioteca por meio de instâncias da classe Document

. A classe Document representa o mecanismo escolhido pelo Lucene para troca de informações entre a aplicação e a biblioteca. Um documento é composto por campos e estes campos por informações. Cada campo possui sua utilidade para a aplicação e sua importância na pesquisa. Por exemplo, campos comuns são: o ID, que não será indexado, mas será importante para que a aplicação localize o documento retornado pela

Page 31: Implementacao de Uma Maquina de Busca Com o Lucene

31

pesquisa; e o TEXT que conterá a cadeia de caracteres a ser indexado e analisado pela biblioteca. O resultado da consulta é um conjunto de documentos ordenado por relevância, ou seja, os itens mais similares a consulta aparecem primeiro.

O Lucene implementa uma linguagem para consulta que proporciona pesquisas booleanas (e.g. Luis AND Inacio AND Silva OR Lula), restritivas (e.g. + George + Rice - eat - pudding), por campos (e.g. animal: monkey AND food: banana), por expressões regulares (e.g. test *, te? t), consultas ponderadas (e.g. jakarta ^ 4 apache) e em range

(e.g. date: [20020101 TO 20030101]). Além disso, ainda permite ao desenvolvedor criar dois tipos de consultas anvançadas: (i) a fuzzy , que utiliza a distância de Levenshtein ao avaliar a proximidade entre a consulta e o documento, e permite informar o nível de similaridade mínimo, como, por exemplo, na consulta " roam ~ 0.8 "; (ii) a busca por proximidade entre palavras, como, por exemplo, a consulta " jakarta apache " ~ 10, que buscará todos os documentos que possuem " jakarta apache " com no máximo 10 palavras entre estas duas da consulta.

Os índices podem ser criados em ambientes distribuídos, aumentando a performance e a escalabilidade da ferramenta. Calcula-se que o Lucene consiga indexar cerca de 20MB de texto por minuto em um computador com um único core de 1.5Ghz. Os arquivos de índices comprimidos ocupam cerca de 25% do tamanho sem compressão.

Instalação

O download da biblioteca deve ser feito pelo endereço http://www.apache.org/dyn/closer. cgi/lucene/java/. Após o download, basta descompactar o arquivo ZIP e colocar o lucene-core-X.Y.Z.jar dentro da pasta de bibliotecas externas de seu projeto java.

Lucene em 5 minutos

Crie um projeto Java e uma classe principal com um método main , onde deverão ser colocados todos os códigos aqui apresentados. Este resumo foi baseado no tutorial Lucene in 5 minutes.

Indexando uma base

Para criar os arquivos de índice, basta instanciar o IndexWriter, adicionar os documentos de sua base a ele, e fechar o arquivo. Como este é um caso simples, usaremos o índice em memória.

// Cria o analyzador StandardAnalyzer analyzer = new StandardAnalyzer(); // Diretório virtual para o índice Directory indexDirectory = new RAMDirectory(); // Cria o arquivo com tamanho ilimitado. IndexWriter w = new IndexWriter(indexDirectory, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED); // Adiciona 4 documentos. addDoc(w, "Lucene in Action"); addDoc(w, "Lucene for Dummies"); addDoc(w, "Managing Gigabytes"); addDoc(w, "The Art of Computer Science");

Page 32: Implementacao de Uma Maquina de Busca Com o Lucene

32

// Fecha o arquivo. w.close();

O método addDoc cria um novo documento, adiciona um texto (text) como título

deste documento e configura este título para ser armazenado e analizado. private static void addDoc(IndexWriter w, String text) throws IOException { Document doc = new Document(); doc.add(new Field("title", text, Field.Store.YES, Field.Index.ANALYZED)); w.addDocument(doc); }

Criando a Consulta

Agora que o índice está pronto, podemos criar uma consulta no campo de título com o texto “ Lucene ”. Neste caso, a biblioteca deve retornar os documentos 1 e 2 como possíveis respostas a esta consulta.

// Faz o parse da consulta e cria uma query do lucene. Query q = new QueryParser("title", analyzer).parse("Lucene");

Repare que usamos o mesmo analyzer na criação do índice e na consulta. É importante que seja o mesmo analisador nos dois processos, ou seja, se o analizador criado para o índice processa, por exemplo, stopwords , o analisador da consulta também deve processar. Caso contrario a resposta do Lucene para as consultas pode não ser boa.

O objeto query criado anteriormente deve então ser repassado a um IndexSearcher:

int maxHits = 10; // Cria o acesso ao índice IndexSearcher searcher = new IndexSearcher(indexDirectory); // Prepara a coleção de resultado TopDocCollector collector = new TopDocCollector(maxHits); // Faz a pesquisa searcher.search(q, collector); // Separa os 10 itens mais relevantes para a consulta. ScoreDoc[] hits = collector.topDocs().scoreDocs; Depois da consulta realizada, o TopDocCollector conterá os 10 textos mais relevantes, ordenados por similaridade em relação a consulta. Para imprimir o resultado, basta varrer o array hits:

// Imprime os documentos retornados. System.out.println("Found " + hits.length + " hits."); for (int i = 0; i < hits.length; ++i) { int docId = hits[i].doc; Document d = searcher.doc(docId); System.out.println((i + 1) + ". " + d.get("title")); } Pronto. O sistema está em funcionamento.

Page 33: Implementacao de Uma Maquina de Busca Com o Lucene

33

Stopwords, Stemming e Sinônimos

Remoção de Stopwords e Stemming são dois procedimentos comuns em qualquer sistema de recuperação de informações. Stopwords é o conjunto de palavras que não são consideradas na busca. Normalmente são palavras muito comuns do idioma ou do domínio pesquisado. Stemming é processo de reduzir as palavras à sua raiz. A raiz de uma palavra é o conjunto de caracteres que está presente em todas as suas derivações.

Para utilizar stopwords é necessário implementar um analisador. O analisador é uma cadeia de filtros onde cada palavra passará, seja na criação do índice ou na consulta. A classe abaixo é um analisador que filtra as stopwords importadas de um arquivo e efetua o Porter stemming como um filtro que retorna apenas os radicais das palavras válidas.

public class TextAnalyzer extends Analyzer { private final Set<String> stopWords; private final boolean usePorterStemming; public TextAnalyzer(Set<String> stopWords, boolean usePorterStemming) { this.stopWords = stopWords; this.usePorterStemming = usePorterStemming; } public TokenStream tokenStream(String fieldName, Reader reader) { TokenStream result = new LowerCaseTokenizer(reader); if (!stopWords.isEmpty()) { result = new StopFilter(result, stopWords, true); } if (usePorterStemming) { result = new PorterStemFilter(result); } return result; } }

A inclusão de sinônimos na consulta do usuário é um processo menos comum, mas que pode aumentar muito a eficiência do sistema de RI. Trata-se de encontrar documentos que utilizam termos não utilizados pelo cliente da consulta, mas que tem o mesmo significado semântico. Para tal, nós baixamos o script para sinônimos feito em Prolog da versão 2.0 da Wordnet (http://www.cogsci.princeton.edu/2.0/WNprolog-2.0.tar.gz) que cria um hash map thread-safe na memória próprio para efetuar pesquisas de sinônimos para qualquer palavra.

O script armazena os sinônimos em um grafo não direcionado. Ou seja, se B é sinônimo de A, A também será sinônimo de B. No entanto, o script não garante que, se A é sinônimo de B e B é sinônimo de C, A seja sinônimo de C. A carga do arquivo leva cerca de 1,5 segundo e consome cerca de 10MB de RAM, mas só precisa ser feito uma vez por execução do programa. Depois de carregado, o método getSynonyms (String) retorna os sinônimos de uma palavra em lowercase em O (1).

Page 34: Implementacao de Uma Maquina de Busca Com o Lucene

34

Por exemplo, a entrada “ The earth, the skies and the space ” sem stemming, sem stop words e com número máximo de 2 sinônimos por palavras resulta na saída “ the earth world globe the skies and the space quad blank ”.

A classe abaixo abre o script da WordNet e o incorpora em um analisador do Lucene. Como já foi dito, um analisador é um filtro palavra a palavra. Esta classe segue a mesma estrutura do analisador anterior para remover stopwords.

public class QueryAnalyser extends Analyzer { private static final String WORDNET_PL_DEFAULT_FILE_PATH = "./resources/wn_s.pl"; private static final SynonymMap synonymMap; static { try { synonymMap = new SynonymMap( new FileInputStream(WORDNET_PL_DEFAULT_FILE_PATH)); } catch (IOException e) { throw new IllegalStateException("could not read wordnet file", e); } } private final TextAnalyzer textAnalyzer; private final int maxSynonyms; public QueryAnalyser(TextAnalyzer textAnalyzer, int maxSynonyms) { this.textAnalyzer = textAnalyzer; this.maxSynonyms = maxSynonyms; } public TokenStream tokenStream(String fieldName, Reader reader) { // Cria SynonimFilter do Lucene passando o mapa de sinônimos já carregado // Retorna um stream de tokens com o original e os sinônimos. SynonymTokenFilter tokenStream = new SynonymTokenFilter( new LowerCaseTokenizer(reader), synonymMap, maxSynonyms); // Trasforma a lista de tokens em String novamente. String query = null; try { query = Utilities.readTokenStream(tokenStream); } catch (IOException e) { throw new IllegalArgumentException("problem reading given reader",e); } StringReader stringReader = new StringReader(query); // Re-passa para o removedor de Stemming e Stopwords return textAnalyzer.tokenStream(fieldName, stringReader); } } ______________________________________________________________________ Fonte:http://vitorpamplona.com/wiki/Introdu%C3%A7%C3%A3o%20ao%20Apache%20Lucene