
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.
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);
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.
O objetivo do indexador é indexar documentos, para tanto é necessário que haja documentos para serem indexados.
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);
É 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");
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 : termoConsequê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:termoConsequência: Irá pesquisar "termo" no campo "campo" nos documentos indexados.Exemplo : +homer +simpsons -houseConsequê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