Friday, 17. October 2008, 16:54:22
Uma das maiores preocupações para o nosso projeto era fazer pesquisas Full Text Search sem sobrecarregar o banco de dados. Apesar de o Postgresql 8.3 ter integrado o TSearch, ainda não estávamos satisfeitos com a performance de maneira geral. Por isso optamos pelo
Sphinx, um sistema de busca que faz a indexação e tem uma boa integração com o
Django. Assim, não temos problema com sobrecarga do banco para a pesquisa e o resultado de muitas pesquisas é quase instantâneo. O maior processamento está na parte do ORM do Django para inicializar o valor de todos os itens, o que é esperado.
O
tutorial do David Cramer é bem completinho, só quero complementar algumas coisas:
Ao fazer o sphinx.conf para o serviço do Sphinx, utilize uma classe padrão e herde para todos os seus índices, aqui vão exemplos do nosso arquivo, note que criamos um índice para as notícias do dia, podendo assim indexar em intervalos curtos sem sobrecarregar o servidor. Eu preferi fazer o arquivo na mão, mas o django-sphinx tem um comando
generate_config_for_model
que gera o arquivo de configuração para você, vale a pena dar uma olhada.
#classe base com informações de conexão
source base
{
type= pgsql
sql_host= 1.1.1.0
sql_user= user
sql_pass= password
sql_db= dbname
sql_port= 5432
}
#índice de notícias de hoje
source news_current : base
{
sql_query= \
SELECT id, section_id, DATE_PART('epoch',published_date) as published_date, headline, story \
FROM news_news WHERE published_date >= (current_date)
sql_attr_uint= section_id
sql_attr_timestamp= published_date
sql_query_info= SELECT * FROM news_news WHERE id=$id
}
index news_latest
{
source= news_current
path= /var/data/news_general
docinfo= extern
charset_type= utf-8
}
#índice de notícias dos últimos 30 dias
source news_thisyear : base
{
sql_query= \
SELECT id, section_id, DATE_PART('epoch',published_date) as published_date, headline, story \
FROM news_news WHERE published_date >= (TIMESTAMP '2008-01-01 00:00:00') \
and published_date < (current_date)
sql_attr_uint= section_id
sql_attr_timestamp= published_date
sql_query_info= SELECT * FROM news_news WHERE id=$id
}
index news_recent
{
source= news_thisyear
path= /var/data/news_recent
docinfo= extern
charset_type= utf-8
}
Outro ponto que não fica muito claro é que é necessário recriar o índice de pesquisa do Sphinx sempre que possível pois ele só se conecta ao banco de dados quando você dá o comando
indexer --nome_indice
e pode ficar algum conteúdo desatualizado.
Por isso colocamos no cron um processo de indexação a cada 10 minutos da notícia do dia, um processo diário das notícias dos últimos 30 dias e um processo mensal de todo o arquivo de notícia do site, assim fica tudo sincronizado sem sobrecarregar o banco.
Outro ponto importante é como deve-se trabalhar com o Timestamp do Postgresql e o Sphinx. Tivemos que usar a função DATE_PART('epoch',published_date) para que ele devolva a data como um inteiro. Também tem um problema com boolean como
mencionado aqui.
É isso aí, pesquisa eficiente e sem dor de cabeça é com o sphinx. Muito em breve vamos ter uma necessidade de pesquisa em muitos conteúdos diferentes com um projeto bem maior, postarei comentários

Abstract: We're using Postgresql and Sphinx for our searches and it has been great. Really fast and reliable. We could get it done quickly following David Cramer's post but I want to point some things:
1st: On sphinx.conf, use a base class for your database connection and extends your indexes from it.
2nd: Split big queries that can change and those that probably won't change so soon. We have a News site so we have one index for today, for the last 30 days and one archive. So we just have to index every 5 minute a small amount of data that must be keep up to date, and on bigger intervals for the rest of them.
3rd: To use timestamp fields on your index, make sure you are using DATE_PART('epoch',published_date) so it will be converted to integer as Sphinx expects. There's also a problem with boolean fields as mentioned here.