PHP Flex Search Encontrando Registros Por Múltiplos Argumentos Numa só Tacada

$inputTextString = 'cano pvc 3mm rosca azul tigre pc';
$baseQuery = 'SELECT * FROM product WHERE 1=1 %s';

$flexQuery = ' %1$s (product.code LIKE \'%%%2$s%%\' OR product.long_desc LIKE \'%%%2$s%%\' OR product.short_desc LIKE \'%%%2$s%%\' OR product.brand LIKE \'%%%2$s%%\' OR product.measure_unit LIKE \'%%%2$s%%\')';
            
$flexWhere = '';
$flexArgs = explode(' ',$inputTextString);
foreach($flexArgs as $flexArg) {
  $flexAnd = empty($flexWhere) ? 'AND(' : 'AND';
  $flexWhere .= vsprintf($flexQuery,[$flexAnd, $flexArg]); 
}

$flexWhere .= empty($flexWhere) ? '' : ')';
$flexSearch = sprintf($baseQuery, $flexWhere);

$conn = mysqli_connect('localhost', 'username', 'password', 'database');
$result = mysqli_query($conn, $flexSearch);

Sabe quando você vai àquele material de construção e o vendedor não consegue achar o produto que você pediu dentro do sistema de vendas? Pois é, que falta de sorte né!

No meu caso eu acho que dei bastante sorte quando iniciei na programação WEB no início dos anos 2000… trabalhando com sistemas eCommerce uma das jóias do nosso aplicativo PHP era a busca de produtos simplesmente informando todas as características para pesquisa num único campo string.

Todas as informações como partes do nome, marca, modelo, dimensões, unidade de medida eram informados num único campo TYPE TEXT simplesmente separando as partes por espaço em branco, o separador universal mais rápido de ser digitado.

Como a técnica não tinha sido nomeada até então eu acabei dando o nome de FLEX SEARCH por que é exatamente isto que este conceito de busca faz, flexibiliza a pesquisa de registros para o operador.. o desenvolvedor que se vire pra fazer o código funcionar.

Observe no código que a busca é flexibilizada ao máximo, pois tentamos encontrar os fragmentos de pesquisa informados não somente na descrição do produto, mas também em outros campos na tabela, e esta busca é feita de forma não obstrutiva, ou seja, a busca tentar encontrar os fragmentos onde for possível mas não requer obrigatoriedade de existência em todos os pontos.

Se você imprimir o conteúdo em $flexSearch você vai encontrar uma query como o SELECT logo abaixo. Então basta simplesmente executar a instrução SQL para obter os registros desejados.

SELECT * FROM product WHERE 1=1  AND( (product.code LIKE '%cano%' OR product.long_desc LIKE '%cano%' OR product.short_desc LIKE '%cano%' OR product.brand LIKE '%cano%' OR product.measure_unit LIKE '%cano%') AND (product.code LIKE '%pvc%' OR product.long_desc LIKE '%pvc%' OR product.short_desc LIKE '%pvc%' OR product.brand LIKE '%pvc%' OR product.measure_unit LIKE '%pvc%') AND (product.code LIKE '%3mm%' OR product.long_desc LIKE '%3mm%' OR product.short_desc LIKE '%3mm%' OR product.brand LIKE '%3mm%' OR product.measure_unit LIKE '%3mm%') AND (product.code LIKE '%rosca%' OR product.long_desc LIKE '%rosca%' OR product.short_desc LIKE '%rosca%' OR product.brand LIKE '%rosca%' OR product.measure_unit LIKE '%rosca%') AND (product.code LIKE '%azul%' OR product.long_desc LIKE '%azul%' OR product.short_desc LIKE '%azul%' OR product.brand LIKE '%azul%' OR product.measure_unit LIKE '%azul%') AND (product.code LIKE '%tigre%' OR product.long_desc LIKE '%tigre%' OR product.short_desc LIKE '%tigre%' OR product.brand LIKE '%tigre%' OR product.measure_unit LIKE '%tigre%') AND (product.code LIKE '%pc%' OR product.long_desc LIKE '%pc%' OR product.short_desc LIKE '%pc%' OR product.brand LIKE '%pc%' OR product.measure_unit LIKE '%pc%'))

Resumindo, a busca só vai falhar se algum fragmento de pesquisa informado não existir em nenhuma das fontes possíveis. O PHP ajuda muito na construção de queries dinâmicas, e este SQL é bastante padrão ANSI e deveria rodar fácil em pelo menos uma dúzia de diferentes bancos de dados.

Da próxima vez que for ao comércio e se deparar com um vendedor em dificuldades, você vai lembrar… vai aí um Flex Search?!!!

Deixe um comentário