Entendendo o Sphinx

Ae!


Este é um, de uma série de três artigos, sobre utilização de Django e Sphinx Search.

Este primeiro tem como objetivo ajudar no entendimento do Sphinx Search, um segundo tratará somente sobre a utilização do Sphinx com o Django, e um terceiro sobre o uso de Django e Sphinx em ambiente de produção.

Então vamos lá!


O que é Sphinx?

O Sphinx é um full-text search engine (Motor de busca de texto), distribuído sobre GPL versão 2.

Ele é um motor de pesquisa autônomo, criado para proporcionar mais velocidade e eficiência nas pesquisas de texto. Além de fornecer funções para outras aplicações, e ter sido especialmente concebido para integrar-se bem com bases de dados SQL e linguagens de scripting (python, php, ruby, etc).
Por que usar o Sphinx?

O principal objetivo do Sphinx é tornar mais escalável os processos de busca em sistemas com grande volumes de dados. O Django, ou qualquer outro framework existente, não é capaz de possuir as mesmas vantagens, por este motivo existem soluções como o Lucene, Solr, Beagle, Sphinx e Xapian. Estas são ferramentas que realmente diminuem absurdamente a carga sobre as aplicações web desenvolvidas, por rodar de maneira otimizada.

Caso necessite de mais informações sobre o Sphinx visite o site oficial do projeto em www.sphinxsearch.com.

 

Instalando o Sphinx

Este documento foi escrito utilizando uma distribuição Linux, mas o método deve funcionar para qualquer SO baseado em UNIX. No site do Sphinx existe versões do software para Windows.

Para instalar no Linux será necessário baixar o código fonte da última versão estável 0.98, e compilá-lo.

As dependências para instalar o Sphinx são um compilador C++ (gcc, g++, etc) e o MySQL com as bibliotecas de desenvolvimento(mysql-server, libmysql++-dev), o mesmo para o PostgreSQL (postgresql-8.3, postgresql-server-dev-8.3).

Execute como root:

$ ./configure
$ make && make install

Feito!! Se não deu erro, nem aconteceu nada estranho, o Sphinx está instalado e pronto para ser utilizado.

 

Como o Sphinx funciona?

 

O Sphinx possui dois programas utilizados para busca e indexação de conteúdo. O primeiro é o indexer, que é responsável por construir a base de dados otimizada para ser utilizada nas buscas. O outro é o searchd, que é o servidor (daemon) responsável por fazer as buscas na base indexada.

O que o indexer faz, é utilizar as configurações de source e index, que serão mostradas no próximo tópico, e montar uma estrutura melhor para realização de buscas. Além das configurações de conexão com o banco de dados. O indexer possui uma parâmetro, chamado sql_query, que trata-se de uma consulta bem elaborada, que retorna uma lista completa com todos os dados, sem filtragem, de uma base de dados. Como o objetivo é a utilização no Django, o exemplo segue o contexto do mesmo:

 

Pegando uma estrutura de relacionamento entre duas tabelas (Categoria e Artigos) e a seguinte regra de relacionamento: um Categoria possui muitos Artigos, e um Artigo pertence a uma Categoria. Tem-se:

class Categoria(models.Model):
title = models.CharField(max_length=200)
def __unicode__(self):
return self.title
class Artigos(models.Model):
tag = models.ForeingKey(Categoria)
title = models.CharField(max_length=200)
content_body = models.TextField()
created_at = models.DateTimeField()
def __unicode__(self):
return self.title

 

Quando é feito a listagem dos Artigos de uma Categoria (Ex. “Anime”) utilizando o ORM do Django, tem-se:

categoria = Categoria.objects.get(title=”Anime”)
artigos = Artigos.objects.filter(tag=categoria)

Fácil!? Duas linhas e todos os Artigos de uma categoria são retornados rapidamente.
Agora, além da categoria, queremos os artigos que possuam em seu título a palavra “Death”.

categoria = Categoria.objects.get(title=”Anime”)
artigos = Artigos.objects.filter(tag=categoria).filter(title__contains=”Death”)

Belezura, o ORM retorna rapidinho uma lista de todos os Artigos com as restrições aplicadas acima. Mas pensando maior ainda.
E se você tem uma estrutura com 4 tabelas e 12 campos que devem ser utilizados na consulta?
Será preciso construir uma consulta bem grande, para garantir o resultado esperado, o que acarretaria na adição de inúmeras chamadas filter() para cada campo que deve ser avaliado, além de consultas paralelas para poder capturar as chaves estrangeiras. Nessa hora a cabeça lateja.
Eis onde entra o Sphinx com o sql_query, ele recolherá todo e qualquer dado retornado como verdadeiro e salvará na base indexada, a consulta ficaria assim:

sql_query = \
SELECT myapp_artigos.id, myapp_artigos.tag, \
myapp_artigos.title, myapp_artigos.content_body, \
myapp_artigos.created_at \
FROM myapp_artigos \
INNER JOIN myapp_categoria \
ON (myapp_artigos.tag = myapp_categoria.id) \
GROUP BY myapp_artigos.id

Pronto, a consulta parece meio grande, mas só será enorme se houver muitas tabelas e campos.

Para finalizar esta parte, executando esta chamada no banco de dados, será retornado todos os ítens relacionados entre as duas tabelas, e o indexer, trabalhará sobre este resultado, gerando a base indexada.

Portanto, quando é realizado uma busca através do Sphinx, ele não mais consulta o banco de dados, somente consulta sua própria base indexada. Mais detalhes sobre busca será mostrado no próximo artigo, quando o Django entrar na história.

Montando o Sphinx.conf

Tanto para o Indexer quanto para o Searchd, é necessário utilizar o mesmo arquivo de configuração, e o mais comum é utilizar o nome sphinx.conf, e colocá-lo no diretório root do seu projeto, isso para facilitar na hora de encontrá-lo.
As seções do sphinx.conf são quatro:
Indexer – é responsável pela configuração do programa Indexer, abaixo segue explicações de cada parâmetro configurável.

Indexer {
# Este parâmetro limita o consumo de memória usado pelo indexador. 
# O padrão é 32M, e o máximo configurável é 2047M.
mem_limit = 256M
# mem_limit = 262144K # o mesmo em KB
# mem_limit = 268435456 # o mesmo em bytes
# Máximo de operações de I/O, o default é 0 (ilimitado)
max_iops    = 40
# O tamanho máximo de operações de I/O permitido, em bytes.  O padrão é 0 (ilimitado)
max_iosize  = 1048576
}


Searchd
– é responsável pela configuração do programa Searchd, abaixo segue explicações de cada parâmetro configurável.

Searchd {
# Timeout de requisições, em segundos. O padrão 5 segundos.
read_timeout = 5
# O número de processos filhos criados pelo servidor. O padrão é 0 (ilimitado)
max_children = 300
# Arquivo de log
log = /var/log/sphinx/searchd.log
# Número da porta TCP do searchd. O padrão é 3312.
port = 3312
# Máximo de ítens que o servidor mantém na RAM para cada index,
# e que pode ser retornado ao cliente. O padrão é 1000
max_matches = 1000
# Arquivo de log de consultas
query_log = /var/log/sphinx/query.log
# Impede que o searchd fique preso em um processo rotativo
# com enormes quantidades de dados pre-cacheados.
seamless_rotate = 1
# Nome do arquivo de ID do processo do searchd.
pid_file = /tmp/searchd.pid
# Endereço IP do servidor searchd. Padrão 0.0.0.0
# Mas pode ser qualquer endereço. Ex. 192.168.0.1
address = 0.0.0.0
}


Agora, as duas configurações mais importantes do Sphinx, as duas seções seguintes do sphinx.conf são o Source e Index.

O sphinx.conf pode possuir vários source e index. Tanto o source quanto o index podem ser extendidos, o que é bem útil para evitar repetições de configurações.
No source você especifica qual tabela do banco de dados, servidor, etc será utilizado para gerar a base indexada, e ele é diretamente relacionado à consulta que será realizada. Mas um index pode possuir vários sources, como será exemplificado mais a frente.

source searchapp_node {
# Tipo de base de dados. Elas podem ser (mysql, pgsql, xmlpipe e xmlpipe2)
type = mysql
# Servidor de banco de dados
sql_host = localhost
# Usuário do banco de dados
sql_user = root
# Senha do usuário
sql_pass =
# Nome da base de dados
sql_db = search_test
# Porta do servidor. O padrão é 3306
sql_port =
# Node do UNIX socket para conectar com o servidor SQL.
sql_sock =
# Pre-consulta que será executada antes da realização da indexação.
# Você pode ter várias.
sql_query_pre = SET SESSION group_concat_max_len = 65535
sql_query_pre = SET NAMES utf8
# Pós-consulta que será executada após a realização da indexação.
sql_query_post =
# Consulta principal da indexação. Será melhor
# explicada na seção como funciona a indexação.
sql_query = SELECT `id`, `title`, `content` FROM `searchapp_node`
# Consulta de informações de documento
sql_query_info = SELECT * FROM `searchapp_node` WHERE `id` = $id
}

Abaixo segue os parâmetros de configuração de um index.

index main {
# Source que será indexado. Podem ser determinados quantos forem necessários.
source = searchapp_node
# source = outro_source_qualquer
# Tipo de encoding de caracteres
charset_type = utf-8
# Tamanho mínimo da palavra a ser buscada.
min_word_len = 3
# Caminho para arquivos que possuem palavras que não devem ser indexadas. 
# Você pode expecificar vários arquivos, separados por um espaço em branco.
stopwords = stopwords-pt_BR.txt stopwords-en.txt
# Este parâmetro e muito importante pois ele habilita a star-sintax
# o permite fazer buscas mais elaboradas.
enable_star = 1
# Permite a passagem de HTML para a base indexada.
html_strip = 0
# Caminho de armazenamento da base indexada.
path = /var/data/sphinx_index_main
}

Finalizando esta parte, agora que já está tudo devidamente configurado, somente é necessário rodar o indexer no prompt de comando, como descrito abaixo.

$ cd /home/usuario/projeto_django
$ indexer –-all

Se houver uma instância do searchd rodando, será necessário utilizar o parâmetro --rotate, para que o indexer automaticamente notifique o servidor sobre as alterações da base.

Também é possível indexer somente um dos index registrados no sphinx.conf, indicando o nome do index no lugar do parâmetro --all:

$ indexer main

Era isso por enquanto, eu vou tentar colocar os novos artigos Django-Sphinx e Uso de Django e Sphinx em ambiente de produção o mais rápido possível.

 

Falow!!

Kd textos em inglês??

Kd textos em inglês?? Parou???

Submitted by Intruder (not verified) on Tue, 28/10/2008 - 10:48.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd><b><i><u> <img>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. Beside the tag style "<foo>" it is also possible to use "[foo]".

More information about formatting options

Sponsorship

Luto

MWOC 2008 - Licencied by Creative Commons
Original template Seopoint Alek 2.0 made by Brian Gilley, customized by Robson Mendonça.