Pesquisar este blog

sexta-feira, 18 de novembro de 2011

Apache Solr Parte 3 - Criando um DAO em java

Com a seguinte chamada e possivel fazer a conexão com o solr


private SolrServer solrServer;
   
    public IndexerAndSearcher() {
        try {
            this.solrServer = new CommonsHttpSolrServer("http://localhost:8983/solr");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

Para fazer uma pesquisa e simples basta:

/**
     *
     * @param field
     * @param text
     */
    public void search(String field, String text) {
        // http://localhost:8983/solr/select/q=*:*&sort=id+asc&version=2.2
        ModifiableSolrParams params = new ModifiableSolrParams();
        params.set("q", field + ":" + text);

        try {
            QueryResponse queryResponse = solrServer.query(params);
           
            SolrDocumentList documents = queryResponse.getResults();
            System.out.println("\n--\n");
            for(SolrDocument document : documents) {
                System.out.println("Document[" + document.getFieldValue("id") + "]");
                System.out.println("\tDocument Fields[" + document.getFieldNames() + "]");
                System.out.println("\tNome: " + document.getFieldValue("nome"));
                System.out.println("\tDescricao: " + document.getFieldValue("descricao"));
            }
        } catch (SolrServerException e) {
            e.printStackTrace();
        }
       
    }

Para adicionar um documento:

/**
     *
     * @param id
     * @param nome
     * @param descricao
     */
    public void addDocument(String id, String nome, String descricao) {
        SolrInputDocument document = new SolrInputDocument();
        document.addField("id", id);
        document.addField("nome", nome);
        document.addField("descricao", descricao);
        try {
            solrServer.add(document);
            solrServer.commit();
            System.out.println("[Document] Evento cadastrado: " + document.toString());
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Chamando os metodos:

public static void main(String[] args) {
        IndexerAndSearcher indexerAndSearcher = new IndexerAndSearcher();
       
        //indexerAndSearcher.addDocument("1", "Cafe com Tapioca", "Evento de Java do CEJUG em Fortaleza");
        //indexerAndSearcher.addBean("2", "EJES", "Encontro de Java");
       
        indexerAndSearcher.findAllDocuments();
       
        //indexerAndSearcher.search("id", "[2 TO 5]");
    }


Essa e uma demostração simples do que pode ser feito para acessar uma base solr no proximo post eu vou colocar uma aplicação que criei para manipular o solr.





Apache Solr Parte 2 - Entendendo as querys

buscas basicas

*;* - qualquer valor em qualquer campo, ou seja, todos os resultados.

formato de resposta

toda a resposta vem dentro de <response/>

a primeira parta da resposta  o responseHeader

- status: sempre 0 a nao ser que algo de muito errado
- QTime - o tempo em milisegundos que o Solr demorou para processar a requisiçao. Devido ao cache, a mesma requisiçao se feita seguidas vezes, o tempo de processamento vai diminuindo

dentro de <result> estao os <doc> que sao os documentos que deram match na consulta

form de busca

Parametros que afetam a busca

q: a query em si

q.op = AND ou OR. Se nao estiver presente entao pega o valor default do schema.xml


df=campo default usado na busca. Se nao estiver presente, usa o definido no schema.xml

fq=filter query, limita o escopo de uma query. Podem ser usadas varias filter query

Parametros que afetam o output dos resultados

start - indice do primeiro documento que deve retornar na query. default 0

rows - n�mero de documentos que devem retornar, começando pelo indice definido em start.

fl - lista de campos que devem retornar na busca (separados por virgula ou espaço). * representa todos os campos

sort - lista de campos separados por virgula, com a ordem (crescente ou descrecente em que devem aparecer)

wt - define o formato de saida

FORMATOS DE SAIDA:

xml - � o default
javabin- usado pelo SorlJ
json
python
php
phps
ruby
xstl

Pode ter formatos de saida personalidos, usar xstl  a forma mais indicada para criar saidas personalizadas

indent - on, off identa a saida da query

echoParams - mostra se os paramtetros da req serao mostrados

Sintaxe de querys

As querys podem ser dividas em mandatOry, proibitivas ou opcionais


mandatory: +Latino, ex: todos os artistas que contenham a palavra Latino
proibitivas: -Latino ex:todos os artistas exceto os que contenham a palavra Latino
optional:


Dois lados mandatarios

Leonardo AND Rosa

equivale a

+Leonardo +Rosa


Dois lados opcionais

Leonardo || Rosa
Leonardo OR Rosa

Leonardo NOT Rosa

equivale a

+Leonardo -Rosa


Sub queries

(Green AND Day) OR (Foo and Fighter)

equivale a (+Green +Day) (+Foo +Fighter)

Queries em frases

"Diego Sena"~ - Permite que essas palavras estejam separadas por ate 3 palavras

Wildcards

W* eX: NOMES QUE COMEÇAM COM W

WI*M ex: nomes que começam com Wi e terminam com M

WI??* ex: nomes que começam com Wi, tem mais dois caracteres e podem ter mais ...


Querys de intervalo

duracao:[3 TO *]

mATEM�TICA COM INTERVALO DE DATAS(oferece adi��o, subtra��o e arredondamento nos v�rios n�veis de uma data)

data_lan�amento:[* TO NOW-2YEAR] //data de lan�amento de 2 anos atr�s at� agora
data_lan�amento:[NOW-2YEAR TO NOW-1YEAR] // NOV/2009 A NOV/2010

Filter query . reduz o escopo de uma busca...

Ex: uma query que retorna todos os produtos da apple ..

ap�s aplicar uma fq .. apenas os produtos da apple com pre�o inferior a 2000 ser�o retornados

Voc� pode conseguir o mesmo efeito de uma filter query fazendo uma subquery

(+marca:apple +preco:[* TO 2000])

por�m � mais vantajoso usar filter query pois

aumenta a performance pois cada fq � cacheada
N�o afeta o score dos documentos encontrados

Facets

funciona como um agrupador

Por campo

&facet=on&facet.field=salesClassification

Por query

&facet=on&facet.query=salesPrice:[1 TO 1000]&facet.query=salesPrice:[1001 TO 2000]

Apache Solr Parte 1 - Entendendo o Schema.xml

O que é:

Solr é uma plataforma de busca do Lucene. O Lucene é uma biblioteca escrita em Java para indexação e busca por textos, enquanto o solr é um servidor de busca que usa o Lucene como core. Antigamente o solr era um projeto separado do Lucene. Agora o Lucene inclui 2 modulos Lucene Core e Solr.

Como funciona:

O solr tem 4 operaçoes básicas: indexar, atualizar, remover e procurar. A operaçao de indexar pode ser feitar de algumas formas:

xml: o formatd do xml é definido pelo schema.xml

json

data import handler: Importa registros direto de um banco de dados para o solr

Importação de arquivos csv

Arquivos binarios: word, pdf, etc...

Utilizando a api solrj para programaticamente inserir documentos

A atualizacão também é feita da mesma forma que a inserção, a diferença é que o solr identifica um documento pelo id (chave primaria) definido no schema, e quando um insert é feito com um id existente, ele apenas atualiza o documento. a remoçao tambem é feita utilizando o id do arquivo

A busca é feita através de queries Lucene via http GET e retorna respostas em XML, JSON, ou resultados binarios, word, pdf, etc...

Alem da biblioteca de busca do Lucene o solr tem algumas extensões proprias.

Conceitos básicos:

http://wiki.apache.org/solr/SolrTerminology

Configurações básicas:

O solr pode rodar em qq servidor de aplicação java JEE (servlet container). Pode ter um nucleo ou multi nucleos (Multicore).

Vantagens e desvantagens:

A biblioteca lucene implementa varios padroes de busca binaria, arvores, etc... que nao precisamos nos preocupar, basta usar sua biblioteca de busca. Com isso a busca por texto performa muito mais do que em um banco de dados.

O solr possui varios tipos de cache, para aumentar ainda mais a performance O solr pode ser replicado facilmente atraves de configuracoes Uma desvantagem é que dependendo da necessidade do seu negocio, seus dados (ex BD), podem demorar a refletir no indice solr.

Schema solr

O schema é dividido basicamente em 3 partes:

Tipos de dados <types><fieldType>:

São as definicoes dos campos solr. Esses campos tem um nome, um tipo (classe solr), algumas propriedades, analyzers e tokenizers. As propriededas mais importantes são indexed (o campo pode ser utilizado em busca, ordenaçao e facet) e stored (o campo aparece no documento retornado pelo solr). As propriedades podem ser sobrescritas na declaraçao dos campos.
 
Campos do solr: <fields><field>: Os campos tem um nome e um tipo (definido na sessao anterior). Tambem tem os campos dinamicos, que podem ser definidos em runtime. Eles possuem um prefixo e quando um documento é indexado se um dos seus campos nao esta definido explicitamente no schema ele verifica se o nome do campo bate com um dinamico e indexa com o nome vindo do documento. Propriedades comuns:
 
indexed = searchable, sortable, and facetablestored = aparece no documento

multivalued = it can appear multiple times in a document

sortMissingLast - se for true os docs q nao possuem o campo de ordenacao vem por ultimo

sortMissingFirst - se for true os doc q nao possuem o campo de ordenacao vem por ultimo

positionIncrementGap - serve para manter a integridade nas buscas em campos multivalued

http://wiki.apache.org/solr/FieldOptionsByUseCase

configuraçoes gerais:

uniquekey - definie a chave primaria do documento (nao é obrigatorio) defaultSearchField - quando a query nao define o campo esse é utilizado default query parser operator: define se por padrao os criterios sao unidos por OR ou AND. o default é OR copyfields - copia o conteudo de um campo para outro. Podemos limitar a qtd de caracteres na copia e podemos copiar varios campos para um só. Similarity - é a classe que define  score de cada documento. Podemos definir uma classe para calcular a similaridade dos documentos. Se nenhuma é especificada a default do solr é utilizada.


Uma outra funcionalidade importante são os poly types. Esses campos são armazenados separadamente, embora o usuário visualize apenas um campo. MoneyType e LatLonType utilizam essa feature. No caso do moneyType ele armazena o valor em um campo e a moeda em outro.

MoneyField é um tipo predefinido do solr para armazenar moeda. Ele usa a funcionalidade de poly field para armazenar o valor e a moeda  separadamente. Basta vc indexar em uma moeda padrao e ele armazena outras moedas configuradas, utilizando a taxa de conversao do arquivo passado na definicao do campo currencyConfig.

LatLonType é o tipo utilizado para armazenar latitude e longitude.

analysers e tokenizers:

stemming: processo de reducao de palavras a sua forma base. Ex.: goleiro, goleador, golaço, sua base é gol...

Analyzers: componentes que pre-processam texto de entrada em tempo de query/indexacao. Nao sao executados em queries wildcard e fuzzy Tokenizer: divide uma serie de caracteres em varios tokens (por campo). So pode existir um em cada analyzer.

Token filters: processam todos os tokens gerados pelo tokenizer. O campo é indexado com o resultado desses tokens.

Um dos filters mais utilizados é WordDelimiterFilter, com as opcoes:

splitOnCaseChange - "PowerShot" => "Power" "Shot"
splitOnNumerics - "j2se" => "j" "2" "se"
generateWordParts - "Power-Shot" => "Power" "Shot"
generateNumberParts - "500-42" => "500" "42"
catenateWords - "wi-fi" => "wifi"
catenateNumbers - "500-42" => "50042"
catenateAll - "wi-fi-4000" => "wifi4000"
preserveOriginal - preserva qq palavra sem alteracoes
protected - preserva as palavras de um aquivo sem alteracoes


Field attributes



NomeDescrição
IndexedFields indexados são buscáveis e ordenáveis. São usados pelo “Solr’s analysis process” para alterar seu conteúdo e melhorar os resultados de busca.
StoredO conteúdo de um Stored Field estão salvos no índice. Pode ser útil para recuperação e destaque de conteúdo.


Um item com indexed=true, pode ser buscável através de query solr. Caso ele esteja Stored=false , não será retornado nada na busca.
Um item com situação inversa a de cima (indexed=false, stored=true) não pode ser buscável através de query (não retorna nada em sua busca), porém em uma busca mais genérica (exemplo: itemStock:true) ele vêm no documento de retorno.


Solr analysis  process


Consiste no processo “Tokenizer” que serve para produzir tokens, que na maioria dos casos consiste em palavras a serem indexadas.
Após essa etapa os “TokenFilters” podem eliminar ou modificar um token antes de indexar.