Para quem precisa disponibilizar um mecanismo de busca para um site, que permita indexacao de conteudos em diversos formatos (PDF, ODT, DOC, registros de banco de dados, etc.), a solucao Lucene Search, da Apache Foundation (http://lucene.apache.org/) supre eficientemente essa demanda.Nesse post, pretendo mostrar, de forma sucinta, como o recurso de indexacao e busca pode ser implementado com Lucene Search, usando um framework JEE, no caso, o JBoss Seam (http://seamframework.org), ou outro qualquer de interesse do desenvolvedor.Primeiro, e preciso permitir que as suas entidades (JPA ou Hibernate) tenham a capacidade de gerar informacoes de indice (metadados), que serao gravados em disco, a cada vez que um dado for alterado no banco. Havera, e logico, uma preocupacao sobre quais campos da entidade (digamos, o tipo Pessoa sera indexado unicamente pelo campo str_nome da tabela pessoa) serao indexados. Para configurar os eventos do Lucene Search, de forma que eventos de escrita no banco atualizem os "listenes" do Lucene, e preciso configurar o arquivo "ejb-jar.xml" ou o "hibernate.cfg.xml", com os seguintes itens de configuracao: <property name="hibernate.search.default.indexBase"> value="./lucene_indexes/"/> <property name="hibernate.ejb.event.post-insert" value="org.hibernate.search.event.FullTextIndexEventListener"/> <property name="hibernate.ejb.event.post-update" value="org.hibernate.search.event.FullTextIndexEventListener"/> <property name="hibernate.ejb.event.post-delete" value="org.hibernate.search.event.FullTextIndexEventListener"/> No caso, a propriedade "hibernate.search.default.indexBase" configura o diretorio onde serao gravados os indices. E permitido usar diretorios relativos, como no caso acima, que configura o diretorio de indices para o caminho lucene_indexes, que sera referenciado dentro do path atual configurado para esse contexto. Dependendo do servidor de aplicacao, o diretorio "." pode referenciar o diretorio server, do diretorio padrao de instalacao do JBoss, ou o server/default/deploy. Caso nao exista o diretorio acima, sera automaticamente criado (criara o diretorio server/default/deploy/lucene_indexes).Outro passo importante e copiar as bibliotecas do Lucene e do Hibernate Search (que serao adicionados no arquivo MANIFEST.MF, no diretorio META-INF): lucene-core.jar hibernate-search.jar hibernate-commons-annotations.jar hibernate-annotations.jar lucene-highlighter-2.1.0.jarApos isso, e necessario inserir as anotacoes especificas do Lucene e do Hibernate Search. A primeira indicara, na declaracao da sua classe POJO (JPA/Hibernate) que ela sera indexada:@Entity@Indexed@Table(name = "relator", schema = "juris")public class Relator implements java.io.Serializable {...E preciso marcar o campo da entidade que representa o indice. Na verdade, qualquer campo unico pode ser usado. A anotacao DocumentId apenas ajudara o Lucene a garantir a unicidade dos registros: @Id @DocumentId @Column(name = "id_relator", unique = true, nullable = false) public short getIdRelator() { return this.idRelator; }Dentro da definicao dessa entidade, agora e necessario especificar quais campos sao indexados, e como eles serao indexados: @Column(name = "str_nome_relator", length = 500) @Length(max = 500) @Field(index=Index.TOKENIZED,store=Store.YES, analyzer= @Analyzer(impl = BrazilianAnalyzer.class)) public String getStrNomeRelator() { return this.strNomeRelator; }Nesse ponto, cabem algumas explicacoes: o parametro index permite dizer se o campo sera quebrado em tokens (trechos de caracteres), ou sera tratado como uma sequencia unica. No caso, por ser um campo String composto por nome e sobrenome do relator, e aconselhavel usar a constante Index.TOKENIZED. O parametro store diz se o campo sera armazenado em arquivo, e pode ser visualizado atraves da ferramenta Luke (http://code.google.com/p/luke/). Essa ferramenta, por sinal, e muito util para estudar a forma com que o Lucene gera os indices em arquivo, permitindo simular buscas usando diferentes analizadores semanticos de linguagens.O outro parametro (analyzer) permite definir um