Pesquisa Sphinx – por que e como usar os índices delta de pesquisa esfinge

Problema:
qualquer pessoa que tenha usado a busca por esfinge sabe que reindexar grandes índices leva muito tempo. O principal problema aqui é que todo o índice é recriado toda vez que você executa uma reindexação.

Solução:
a maneira de lidar com isso é usando atualizações de índice delta com mesclagem de índice. A ideia é ter 2 índices:
o “principal” e o grande índice para os dados antigos (inalterados) e
um pequeno “delta” para os novos dados (recentemente alterados). Portanto, em vez de reindexar o índice “principal”, você deve apenas reindexar o “delta” a cada poucos minutos.
Depois de um tempo (uma vez por dia), você deve mesclar o índice “delta” e o índice “principal” (dependendo do tamanho do delta).
Isso é chamado de esquema “principal + delta”.

Como fazer:
Tendo uma tabela “documentos” com os campos: “id, título, corpo”, criamos o índice de pesquisa do esfinge da seguinte maneira:

# in sphinx.conf
source main

{
type
= mysql
...
sql_query
= SELECT id, title, body FROM documents
}

index main

{
source
= main
...
}

Como você pode ver, o sql_query principal nos dá todos os documentos da tabela de documentos. A ideia do esquema “main + delta” é que toda vez que você reindexar main, você terá que armazenar o último id processado em algum lugar, para que o delta possa começar a partir daí e processar uma pequena quantidade de registros.

Então, primeiro, crie esta tabela no mysql para armazenar esse id:

CREATE TABLE sph_counter
(
counter_id INTEGER PRIMARY KEY NOT NULL
,
max_doc_id INTEGER NOT NULL

);

Então, em sphinx.conf:

source main
{
# ...
sql_query_pre
= SET NAMES utf8
sql_query_pre
= REPLACE INTO sph_counter SELECT 1, MAX(id) FROM documents
sql_query
= SELECT id, title, body FROM documents
WHERE id
<=( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 )
}

source delta
: main
{
sql_query_pre
= SET NAMES utf8
sql_query
= SELECT id, title, body FROM documents
WHERE id
>( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 )
}

index main

{
source
= main
path
= /path/to/main
# ... all the other settings
}

# note how all other settings are copied from main,
# but source and path are overridden (they MUST be)
index delta
: main
{
source
= delta
path
= /path/to/delta
}

Como é que isso funciona? Como você pode ver na especificação principal, uma consulta de pré-busca chamada sql query pre aparece. Essa consulta é executada antes da consulta principal (você pode ter várias delas).

REPLACE INTO sph_counter SELECT 1, MAX(id) FROM documents

Nossa consulta de pré-busca atualiza um registro na tabela sph_counter para ser usado posteriormente pelo delta. Este registro irá armazenar o max (id) de nossa tabela de documentos no momento da indexação, então a consulta principal obterá documentos com id menor ou igual a esse máximo e a consulta delta com ids maiores que esse máximo.

Em resumo, você atualiza o principal de vez em quando e o delta de vez em quando. main obterá TODOS os documentos até o momento de sua atualização e o delta obterá todos os novos.

Em seu código, você terá que pesquisar em ambos os índices:

$sphinxClient->Query(“this is my search query”, main delta”);

A indexação do main também levará muito tempo, mas você ficará meio “ativo” porque o delta será atualizado muito rapidamente.
Em vez de reindexar o principal, você pode mesclar os dois índices e apenas atualizar o delta. Vou escrever sobre a fusão em um post futuro.

Links:
http://av4tar.blogspot.com
http://sphinxsearch.com/
http://www.ivinco.com/