Ao trabalhar com o motor de busca Sphinx, é comum surgir a necessidade de realizar pesquisas que abrangem mais de um índice ao mesmo tempo. No entanto, o comportamento do motor em relação aos metadados e atributos retornados apresenta particularidades que impactam o desenvolvimento da aplicação.
Observações Fundamentais
- Interseção de Atribuots: Quando uma consulta é executada em múltiplos índices, o conjunto de atributos (
attrs) retornado no resultado final conterá apenas os campos que são comuns a todos os índices envolvidos. Se um atributo existir no Índice A, mas não no Índice B, ele será omitido no resultado consolidado. - Ambiguidade no Campo Fields: O array de
fieldsretornado nos metadados da consulta múltipla muitas vezes reflete a estrutura do primeiro índice declarado, o que pode não representar fielmente a totalidade dos campos de pesquisa de todos os índices.
Configuração do Ambiente de Teste
Para ilustrar esse comportamento, consideer a configuração de dois índices distintos: idx_marcas e idx_categorias. Ambos compartilham informações básicas do produto, mas possuem campos específicos de texto e atributos.
# Configuração do Índice de Marcas
source src_marcas {
sql_query = SELECT id, id AS id_referencia, id_unidade, titulo_marca FROM tabela_marcas
sql_attr_uint = id_unidade
sql_attr_uint = id_referencia
sql_field_string = titulo_marca
}
# Configuração do Índice de Categorias
source src_categorias {
sql_query = SELECT id, id AS id_referencia, id_unidade, nome_categoria FROM tabela_categorias
sql_attr_uint = id_unidade
sql_attr_uint = id_referencia
sql_field_string = nome_categoria
}
Neste cenário, id_unidade e id_referencia são atributos numéricos presentes em ambos. Já titulo_marca e nome_categoria são campos de texto específicos de seus respectivos índices.
Execução de Consultas via PHP
Abaixo, o exemplo de como o Sphinx lida com as requisições dependendo de como os índices são chamados na API:
// Instanciação do cliente Sphinx
$cliente = new SphinxClient();
// Cenário 1: Consulta em índice individual
$cliente->AddQuery('equipamento', 'idx_marcas');
// Retorno: Contém id_unidade, id_referencia e titulo_marca
// Cenário 2: Consulta em múltiplos índices combinados
$cliente->AddQuery('equipamento', 'idx_marcas, idx_categorias');
// Retorno: Contém apenas id_unidade e id_referencia (a interseção)
$resultados = $cliente->RunQueries();
Análise dos Resultados
Ao analisar o dump dos dados retornados no Cenário 2, observa-se o seguinte comportamento nos matches:
// Estrutura simplificada do retorno para múltiplos índices
[matches] => Array (
[0] => Array (
[id] => 101
[weight] => 1
[attrs] => Array (
[id_referencia] => 101
[id_unidade] => 5
)
)
[1] => Array (
[id] => 202
[weight] => 1
[attrs] => Array (
[id_referencia] => 202
[id_unidade] => 5
)
)
)
Embora a pesquisa por texto completo funcione corretamente e localize documentos que contenham a palavra "equipamento" tanto em titulo_marca quanto em nome_categoria, os valores desses campos de texto (definidos como sql_field_string) não aparecem no array attrs porque não são comuns a ambos os índices.
Se a ordem de chamada for invertida para 'idx_categorias, idx_marcas', o Sphinx manterá a lógica de retornar apenas a interseção dos atributos, embora o cabeçalho de metadados possa mudar para indicar os campos do índice idx_categorias como referência primária.
Para garantir que campos específicos sejam retornados em buscas multi-índice, é necessário padronizar os nomes dos atributos em todos os sources do arquivo de configuração do Sphinx, garantindo que a estrutura de saída seja idêntica antre eles.