Back-End

2 ago, 2013

Como usar o Sphinx para dar maior relevância para palavras

Publicidade

Olá, pessoal!

Há algum tempo estou trabalhando com o Sphinx, um search server open source bastante utilizado pela comunidade.

No projeto em que trabalhamos com Rails 3.X, optamos por usar a gem Thinking-Sphinx, que está atualmente na sua terceira versão e é extremamente simples de trabalhar. Como a ideia aqui não é fazer um tutorial de como trabalhar com o Thinking Sphinx, para quem não faz ideia do que se trata, é olhar algum artigo de instalação e utilizado que é muito bem explicado.

Rankeando

Um dos recursos mais bacanas em todo search server é a capacidade de rankear os resultados. Rankear um resultado, resumidamente, é poder dizer à search engine como deve ser  dada relevância para cada resultado. Por exemplo, vamos supor que você tenha uma loja que vende instrumentos musicais e tenha dois produtos:

  • Guitarra Gibson Les Paul
  • Captador para Guitarra

Se você buscar pela palavra “Guitarra“, no MySQL por exemplo, você vai trazer os dois. Mas, olhando atentamente e pensando logicamente, se o usuário digita apenas guitarra, provavelmente “Guitarra Gibson Les Paul” é muito mais relevante que “Captador para Guitarra” se pensarmos que a pessoa está buscando provavelmente uma guitarra para comprar.

É nesse ponto que os rankers entram. Eles são algoritmos que definem várias formas de gerar essa relevância. No Sphinx temos rankers de proximidade de palavras, rankers que contam quantas palavras existem no texto e por aí vai (veja os tipos para o Thinking Sphinx aqui).

Maior relevância para palavras no início da frase

No meu caso, precisava de um ranker que me desse maior relevância para as palavras que apareciam mais no inicio do texto, como no caso exposto acima. Como não encontrei a referência no site do Thinking Sphinx, acabei achando no site do Sphinx e algumas referências no Stack Overflow o ranker SPH04. Ele é baseado no SPH_RANK_PROXIMITY_BM25 (que no Thinking Sphinx é o ranker default), mas com uma diferença importante: ele dá uma relevância maior para as palavras que aparecem mais no início da frase.

Bingo!

Por exemplo, se eu tenho um modelo produto indexado assim:

[rails]ThinkingSphinx::Index.define :produto, :with => :active_record do

indexes :nome

end[/rails]

A busca deve ser feita da seguinte maneira:

[rails]Produto.search "Guitarra", ranker: "SPH04"[/rails]

Com isso, a busca retornará com maior relevância (ou seja, primeiro) os registros que tiveram o termo “Guitarra” mais no início no nome.

Até a próxima.