DevSecOps

19 dez, 2012

Como utilizar o Spell Checker do Apache Solr

Publicidade

Quem não conhece o famoso “Você quis dizer/Did you mean” do Google?

O componente SpellCheck do Apache Solr fornece sugestões de consulta com base em termos semelhantes. A base de sugestões pode ser desde termos baseado em um campo que você definiu no seu xml de configuração, como arquivos de texto externos, ou até mesmo campos em um outro índice!

Esse componente ainda é muito pouco explorado aqui no Brasil. Quando visito um site de e-commerce, a primeira coisa que faço por vício é digitar o nome do produto errado para analisar o comportamento da engine de busca de onde estou comprando.

Quando eu implementei isso em uma empresa que trabalhei, o resultado positivo foi imediato!

Um site que comercializa veículos (http://www.meucarronovo.com.br), onde o carro mais popular do Brasil é de uma fabricante  alemã (Volkswagen), mas a maioria dos consumidores não sabe escrever o nome dessa fabricante – Volks,Wolks,Volksvagem,Wolksvagem – estas foram algumas das formas pela qual o usuário tentava chegar a esse veículo.

No próximo artigo, vamos falar sobre como associar palavras que têm significado idêntico ou muito semelhante ao de outra (sinônimos) no Apache Solr.

Primeiro precisamos especificar a fonte de termos no nosso amigo solrconfig.xml. Existem quatro abordagens para verificação ortográfica no Apache Solr.

IndexBasedSpellChecker usa um índice  do Apache Solr como referência para um índice paralelo usado para verificação ortográfica. Em um português mais claro, ele gera um dicionário de palavras baseado em seus documentos e o usa sempre que uma consulta no índice é feita.

Esse cara exige que você defina um campo como base para os termos de índice. Uma prática bem comum e que eu costumo usar é copiar os termos de alguns campos  para outro campo criado apenas para verificação ortográfica.

Um rápido exemplo de como configurar o solrconfig.xml com o IndexBasedSpellChecker:

<searchComponent name="spellcheck">
    <lst name="spellchecker">
      <str name="classname">solr.IndexBasedSpellChecker</str>
      <str name="spellcheckIndexDir">./spellchecker</str>
      <str name="field">Aqui o nome do campo</str>
      <str name="buildOnCommit">true</str>
    </lst>
</searchComponent>

Explicando o bloco acima linha a linha:

Linha 1 – Na primeira linha, definimos que o searchComponent deve usar o solr.SpellCheckComponent.

Linha 3 – O nome da classe (classname) é a implementação do SpellCheckComponent; nele, definimos que tipo de análise nosso Spell Checking vai usar. Neste caso, vamos colocar o solr.IndexBasedSpellChecker.

obs: Definir o nome da classe não é obrigatório! Se você não definir, por padrão ele vai setar o  IndexBasedSpellChecker.

Linha 4 – O spellcheckIndexDir define onde está o diretório que contém o índice de verificação ortográfica.

Linha 5 – O campo (field) informa o campo de origem das palavras que você vai utilizar para fazer a correção ortográfica. Quando você escolher um campo para o índice de verificação ortográfica,  se esse campo tem muitas variações de sinônimos, seu dicionário será criado com essas variações.

Linha 6 – E, por último, o  buildOnCommit informa se o seu índice vai construir o índice de verificação ortográfica em cada commit, ou seja, cada vez que novos documentos são adicionados ao índice). Ele não é obrigatório e pode ser omitido se você  defini-lo como falso.

<str name="buildOnCommit">false</str>

DirectSolrSpellChecker utiliza termos do índice Solr sem a construção de um índice paralelo, como o IndexBasedSpellChecker. Falam que esse cara ainda está em desenvolvimento, mas já é muito usado.

Uma grande vantagem do uso do DirectSolrSpellChecker é que não ser preciso construir com frequência, ou seja,  significa que os termos são sempre atualizados com os termos do índice.

Um rápido exemplo de como configurar o solrconfig.xml com o DirectSolrSpellChecker:

<searchComponent name="spellcheck">
 <lst name="spellchecker">
   <str name="name">default</str>
   <str name="field">Aqui o nome do campo</str>
   <str name="classname">solr.DirectSolrSpellChecker</str>
   <str name="distanceMeasure">internal</str>
   <float name="accuracy">0.5</float>
   <int name="maxEdits">2</int>
   <int name="minPrefix">1</int>
   <int name="maxInspections">5</int>
   <int name="minQueryLength">4</int>
   <float name="maxQueryFrequency">0.01</float>
   <float name="thresholdTokenFrequency">.01</float>
 </lst>
</searchComponent>

Linha 4 – Igual o exemplo anterior (IndexBasedSpellChecker), você precisa especificar um campo (field) a ser usado para as sugestões.

Linha 6 – O distanceMeasure define a métrica para usar durante a consulta de verificação ortográfica. O valor interno (internal) utiliza o padrão Levenshtein (Não sabe o que é isso? Clique aqui e veja na Wikipedia).

Esse corretor ortográfico consulta o índice principalmas você pode limitar a frequência com que ele o consulta, evitando quaisquer conflitos de performance/desempenho originadas por uma quantidade massiva de consultas.

Linha 7 – A  precisão (accuracy) define o limite para uma sugestão válida.

Linha 8 – O maxEdits define o número de alterações permitidas. Se você defini-lo para 1, você irá reduzir o número de sugestões possíveis, por padrão é utilizado 2.

Linha 9 – O minPrefix define o número mínimo de caracteres que os termos devem ter. Por exemplo, você informando 1, nesse caso será entendido que todas as sugestões começam com a mesma letra.

Linha 10 – O  maxInspections define o número máximo de possibilidades possíveis de revisão antes de retornar o resultado. O padrão desse campo(field) é de 5.

Linha 11 – O minQueryLength define quantos caracteres devem estar na consulta (query) antes de retornar sugestões. O padrão nesse caso é de 4.

Linha 12 – O maxQueryFrequency define o limite máximo de documentos que um termo deve mostrar antes de ser considerado como uma sugestão. Nesse caso, você pode usar um percentual ou um valor inteiro.
Dica: Um limite inferior é melhor para índices pequenos. 

Linha 13 – O tresholdTokenFrequency define o número mínimo de documentos que um termo deve mostrar. Ele também pode ser definido valores em percentuais ou inteiro, igual ao maxQueryFrequency.

FileBasedSpellChecker usa um arquivo externo como um dicionário ortográfico. Isso pode ser muito útil se você precisar usar o Apache Solr como um servidor de correção ortográfica/sugestões de ortografia.

Um rápido exemplo de como configurar o solrconfig.xml com o FileBasedSpellChecker:

<searchComponent name="spellcheck">
   <lst name="spellchecker">
      <str name="classname">solr.FileBasedSpellChecker</str>
      <str name="name">arquivo</str>
      <str name="sourceLocation">nome-do-arquivo.txt</str>
      <str name="characterEncoding">UTF-8</str>
      <str name="spellcheckIndexDir">./spellcheckerFile</str>
   </lst>
</searchComponent>

A configuração desse modelo de Spell Checker é mais simples que os citados anteriormente, basicamente você define onde está  o arquivo em  sourceLocation e depois, em characterEncoding, você define a codificação dos termos contidos no seu arquivo de sugestão.

WordBreakSolrSpellChecker é uma implantação paralela que retorna sugestões combinando os termos da consulta (query) adjacentes com/ou termos quebrados em várias palavras. Ele pode encontrar erros ortográficos resultantes de espaços desnecessários (São    Paulo por exemplo).

Um rápido exemplo (tá ficando repetitivo isso, LOL)  de como configurar o solrconfig.xml com o WordBreakSolrSpellChecker:

<searchComponent name="spellcheck">
  <lst name="spellchecker">
   <str name="name">wordbreak</str>
   <str name="classname">solr.WordBreakSolrSpellChecker</str>
   <str name="field">Aqui o nome do campo a ser indexado</str>
   <str name="combineWords">true</str>
   <str name="breakWords">true</str>
   <int name="maxChanges">10</int>
 </lst>
</searchComponent>

Se vocês leram tudo até aqui, devem ter percebido que a configuração desse corretor ortográfico é bem semelhante aos corretores citados anteriormente. Temos apenas dois parâmetros novos:

combineWords define se as palavras vão ser combinadas em uma pesquisa (por  padrão, ele vem true).

breakWords define se as palavras devem ser quebradas em uma pesquisa  (o padrão é true também).

maxChanges define quantas vezes o corretor ortográfico deve verificar possibilidades de agrupamento contra o índice (o padrão é 10  e ele só aceita inteiros).

Você pode configurar o Spell Checker com um verificador ortográfico padrão, que é o DirectSolrSpellChecker. Os resultados desse verificador ortográfico são combinados e agrupados, e podem conter uma mistura de correções de verificadores ortográficos.

Simples! Se você está lendo este artigo, provavelmente já tem um Handler de consulta configurado. Então, basta adicionar a chamada do componente no seu handler como no exemplo abaixo:

<arr name=”last-components”>
<str>spellcheck</str>
</arr>

Perguntas frequentes:

1 – Posso ter vários Request Handlers – cada um com um tipo de Corretor Ortográfico Spell Checker? Sim!

2 – Como as sugestões são retornadas? No retorno da sua consulta. Abaixo, um exemplo do retorno em um XML:

<lst name="spellcheck">
        <lst name="suggestions">
                <lst name="pejot">
                        <int name="numFound">1</int>
                        <arr name="suggestion">
                                <str>peugeot</str>
                        </arr>
                </lst>
                <lst name="fRamengo">
                        <int name="numFound">1</int>
                        <arr name="suggestion">
                                <str>Flamengo</str>
                        </arr>
                </lst>
        </lst>
</lst>

Espero que tenha ficado mais claro agora como você pode utilizar o Spell Checker/Corretor Ortográfico do Apache Solr. É um assunto longo e, nos próximos artigos, irei falar sobre os parâmetros que o Spell Checker/Corretor Ortográfico disponibiliza para o Administrador do Apache Solr e também falaremos sobre Spell Checker distribuído em diferentes índices.