A medida que os websites cresce, pesquisas como “LIKE title ‘%search term%’” torna-se inconfiável. Existem soluções muito boas como Sphinx, Lucene, etc, você nem sempre pode ter Sphinx instalado (em servidores compartilhados não é possivel) sendo assim outra solução deve ser escolhida.
O MySQL suporta full-text indexing, mas ele não dá um grande controle sobre o índice real. Felizmente, a equipe do Zend trabalho maravilhosamente e implementou 100% da pesquisa Lucene no PHP. Zend_Search_Lucene faz parte do Zend Framework, mas como todos os módulos é executado de forma quase independente (ele usa Zend_Exception, etc.)
Como você começar a indexação de dados? O manual do Zend tem bons exemplos de como iniciar com Lucene, mas para criar um index de amostra você pode usar esse código (você precisa ter auto-loading habilitado e conexão db disponíveis):
// Criando um indece
$index = Zend_Search_Lucene::create('indexes/products');
$sql = "select product_name, product_url from products";
$results = $db->fetchAll($sql);
foreach ($results as $result)
{
$doc = new Zend_Search_Lucene_Document();
// Armazena a URL do documento para identificá-lo em resultados de pesquisa
$doc->addField(
Zend_Search_Lucene_Field::UnIndexed('url', $result->product_url));
// Titulo do documento de indice
$doc->addField(
Zend_Search_Lucene_Field::Text('title', $result->product_name));
// Adiciona o documento ao índice
$index->addDocument($doc);
}
// Optimize index.
$index->optimize();
Este simples código irá selecionar as informação dos produtos do banco de dados, percorrerá os resultados e adicionara os documentos no index. Neste exemplo eu deixei a url como UnIndexed, porque eu fazei a pesquisa somente pelo título, mas Lucene permite outros tipos de campo. Na maioria dos casos, o texto de descrição do produto deve ser adicionado (ou talvez até indexados).
Buscando através do índice é ainda mais fácil. Uma coisa que você precisa saber é como construir pesquisas em linguagem de consulta. Exemplo:
// Abre o index
$index = Zend_Search_Lucene::open('indexes/products');
$query = 'title:"Apple MacBook"';
// Procura pela query
$hits = $index->find($query);
foreach ($hits as $hit) {
echo $hit->score . " ";
echo $hit->title . " ";
echo $hit->url . PHP_EOL;
}
Eu tentei criar um índice de 6.000 produtos (0,7 MB), ele foi criado em cerca de 3 minutos e todas as pesquisas tem cerca de 0,1 s. Eu testei no meu laptop, sem APC e com o Apache padrão. Em servidores esta tarefa seria executar muito mais rápida, mas 0,1 para a pesquisa não é tão ruim assim.
Zend_Search_Lucene não vai mudar o Sphinx ou o Lucene, mas em ambientes limitados (como servidores compartilhados) ele pode ser bastante útil. Ele suporta muitos tipos de consulta: consultas por frase, consultas booleanas, consultas curinga, consultas de proximidade, de alcance e muitas outras, o que dificilmente pode ser alcançado com o uso de index full-text no MySQL.
Traduzido de Juozas devBlog