Nota rápida: o pessoal da InfoQ publicou meu artigo sobre Implementing Google's "Did you mean" Feature In Java. Todo feedback será bem-vindo.Pesquisar
Mostrando postagens com marcador lucene. Mostrar todas as postagens
Mostrando postagens com marcador lucene. Mostrar todas as postagens
sexta-feira, 9 de abril de 2010
Artigo publicado na InfoQ Gringa
Nota rápida: o pessoal da InfoQ publicou meu artigo sobre Implementing Google's "Did you mean" Feature In Java. Todo feedback será bem-vindo.quinta-feira, 3 de dezembro de 2009
Adicione o recurso "você quis dizer" nas suas aplicações Java

SpellChecker - Uma extensão no Lucene
Continuando brincando com Lucene, no novo Lucene 3.0.0 encontrei uma pasta contrib na qual há libs diversas. Uma delas é o SpellChecker que lhe oferece recursos para que você implemente em suas aplicações java (web ou desktop) recursos como "Você quis dizer".Recurso Você quis dizer
Imagine : Você é dono de uma loja virtual na qual é oferecido DVDs para venda. Um fanático pelo ator Arnold Schwarzenegger entra no sua loja e tem em mente comprar todos os DVDs desse ator (hoje, governador) a primeira ação do usuário é digitar o nome do ator no campo busca. Facilmente ele irá errar a digitação do nome, por exemplo digitando "arnold swuazeneger", e isso não deveria ser algo impeditivo para compra dos DVDs. Para esse problema bastaria a solução do tipo "Você quis dizer foo" implementada pelo Google Inc. no seu motor de busca. Você consegue esse mesmo, ou próximo, efeito em suas buscas utilizando uma das extensões do Lucene, chamada de SpellChecker. O exemplo-código abaixo é simples e demonstra como fazer isso.Código
Directory diretorioDicionario = new RAMDirectory();
//criação do diretório
SpellChecker sp = new SpellChecker(diretorioDicionario);
//instânciação do objeto SpellChecker
sp.indexDictionary(new PlainTextDictionary(new File("dicionario.txt")));
//indexação do Dictionary (há duas implementações).
String pesquisa = "arnold swuazeneger";
//seu termo pesquiado
int numeroDeSugestoes = 5;
//número de sugestões similares
String[] similares = sp.suggestSimilar(pesquisa, numeroDeSugestoes);
//as sugestões em si.
System.out.println("Seu Termo : " + pesquisa);
for (String palavra : similares) {
System.out.println("Você quis dizer: " + palavra);
}
pesquisa = "bava";
similares = sp.suggestSimilar(pesquisa, numeroDeSugestoes);
System.out.println("Seu Termo : " + pesquisa);
for (String palavra : similares) {
System.out.println("Você quis dizer: " + palavra);
}
Saída
Seu Termo : arnold swuazeneger
Você quis dizer: arnold schwarzenegger
Seu Termo : bava
Você quis dizer: java
Você quis dizer: lava
Você quis dizer: bala
Arquivo dicionario.txt:
arnold schwarzenegger
jean claude van damme
java
lava
bala
jean claude van damme
java
lava
bala
Conclusão
Nem sempre é tão difícil quanto parece, sempre há uma roda já pronta para seu problema. Você ainda pode ajustar a acurácia da pesquisa pelo método setAccuracy do SpellChecker. Claro que o uso do recurso em produção requer mais e mais atenção quanto ao diretório e o dicionário de busca. Baseado nos códigos acima, facilmente você consegue levar essa características para seus sistemas Java Web ( JSF - JavaServer Faces, Struts, JSP).
Marcadores:
aplicações web,
google,
java,
lucene,
spellchecker,
voce quis dizer
terça-feira, 1 de dezembro de 2009
Tutorial Apache Lucene 3.0.0 - motor de busca textual

Lucene um motor de busca textual
No dia 25 de novembro foi lançado a nova versão do motor de busca Lucene, a versão 3.0.0. Lucene é um framework de alta performance para busca textual feito em java. (há versões para php e .net também) Uma das características marcantes dele é a integração com Hadoop. (um framework para computação distribuida - que possui, dentre outros, um MapReduce e um sistema de arquivos distribuido HDFS)
Porque usar Lucene?
Imagine o seguinte cenário: Seu usuário deseja criar um modulo de gerenciamento de artigos e também expó-los na Internet. As informações do artigo são: título, autor e o contéudo. Normalmente cada artigo desse contém cerca de 1500 palavras e o usuário poderá buscar pelo conteudo desses artigos. Suponha que há 1 milhão e meio de artigos para serem cadastrados, o simples uso de um banco de dados e o operador LIKE '%palavra%' é inviável. E aí que entra um bom framework de busca textual, usá-lo passa ser a solução mais tranquila e viável. Além de trazer velocidade, também traz outras características nas buscas que dificilmente fariamos codificando tudo do zero.
Domain-Specific Language | Ubiquitous Language
Há vários termos usados na terminologia do framework, os principais são: Documento, Campo, Diretório, Indexador, Pesquisador, Analisador e Termo.
- Documento - é o conjunto de dados que você deseja indexar, por ex. título, conteudo e autor formam o documento artigo, pode ser visto como um objeto no lucene é visto como Document.
- Campo - é o dado, identificado, que pode ser analogo a um campo de uma tabela ou uma propriedade de um objeto no lucene é visto como Field.
- Diretório - conceito abstrato que denota um local para guardar os índices no lucene é visto como uma interface Directory, que possui diversas implementações DbDirectory, FSDirectory, JEDirectory, RAMDirectory.
- Indexador - é o responsável por indexar os documentos num diretorio no lucene é visto, geralmente, como IndexWriter.
- Pesquisador - responsável por pesquisar uma Query no diretorio de índices, no lucene é visto como Searcher.
- Analisador - atua como um filtro e faz uma pré-avaliação do que pode ser indexado ou não, no lucene há uma lista de vários analisadores.
- Termo - pode ser visto como objeto que pode ser usado como parametro da pesquisa, composto pelo nome do campo e o valor a ser pesquisado, no lucene é visto como Term.
Como isso funciona?
A descrição a seguir é um resumo bem simplificado sobre o funcionamento de um motor de busca textual. A primeira fase, geralmente, é a indexação do documento, nessa fase o documento é analizado (por um Analizer que também já retira as stopwords) para posteriomente ser indexado.
O objetivo do indexador é indexar documentos, para tanto é necessário que haja documentos para serem indexados.
No Lucene você pode criar um índice usando o IndexWriter, a criação desse objeto envolve dizer onde será (ou está) o diretório dos índices, qual analizador você irá utilizar, se irá criar o indice e qual a quantidade máxima de campos.SetstopWords = new HashSet stopWords.add("it");();
stopWords.add("the");
stopWords.add("is");IndexWriter writer = new IndexWriter(FSDirectory.open(INDEX_DIR),
new StandardAnalyzer(Version.LUCENE_CURRENT,
stopWords),
false,
IndexWriter.MaxFieldLength.LIMITED);
O objetivo do indexador é indexar documentos, para tanto é necessário que haja documentos para serem indexados.
É o objetivo final de todo processo de busca textual é mesmo a busca em si.Document doc = new Document();
doc.add(new Field("nomedocampo", "valores a serem guardados", 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);
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");
Recursos na busca de documentos
Quando se faz uma pesquisa por documentos no Lucene podemos utilizar de alguns operadores (+, -, AND, NOT, OR, * e etc.) juntamente com o termo pesquisado ou apenas pesquisar uma frase completa.
Exemplo : termo
Consequência: Irá pesquisar a palavra "termo" nos documentos indexados.
Exemplo : termo OR palavra ( == termo palavra)
Consequência: Irá pesquisar "termo" ou "palavra" nos documentos indexados.
Exemplo : +termo +palavra ( == termo AND palavra)
Consequência: Irá pesquisar "termo" e "palavra" nos documentos indexados.
Exemplo : campo:termo
Consequência: Irá pesquisar "termo" no campo "campo" nos documentos indexados.
Exemplo : +homer +simpsons -house
Consequência: Irá pesquisar documentos que contenham homer e simpsons e não tenha house.
Exemplo : "termo exato"
Consequência: Irá pesquisar documentos que contenham exatamente "termo exato".
Exemplo : java*
Consequência: Irá pesquisar documentos que contenham palavras que começem com java (javadb, javanet...).
Exemplo : java~
Consequência: Irá pesquisar documentos que contenham palavras similares a java como por ex. lava, jaba...
Finalizando tive as seguintes impressões sobre essa nova versão do Lucene.
Prós:
- Maior facilidade para uso do framework, ex: criações de Fields estão bem mais fluentes.
- Sensível otimização nos tempos de busca e indexação.
Contras:
- Otimas ferramentas como luke ainda não tem suporte para a versão 3.0.0. (mas já há uma solicitação aberta para tal mudança.)
- Muitas mudanças no core do framework; o que fez livros mais antigos quase perderem seu valor.
Referências
Marcadores:
busca textual,
engine text,
full text search,
google,
java,
lucene,
programacao,
tutorial
Assinar:
Postagens (Atom)