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?? Parou???
- reply
Submitted by Intruder (not verified) on Tue, 28/10/2008 - 10:48.Post new comment