Essa semana tive que implementar em um dos meus projetos um sistema de busca full-text. como estou utilizando o Mysql, ele possui um mecanismo de pesquisa integrado. Há outras bibliotecas de pesquisa como o Lucene, Xapian e Sphinx e todas elas possuem modulos para integra-las ao Django(django-search-lucene, djapian e django-sphinx ) mas no meu caso, como estou utilizando uma hospedagem compartilhada, tenho certas restrições para instalar algumas bibliotecas, portanto tive que partir para esta alternativa.
Bom, vamos ao que é necessário para funcionar a busca:
digamos que você possui um model de noticias:
class Artigo(models.Model):
data_publicacao = models.DateTimeField("Data de Publicação", default=datetime.now)
titulo = models.CharField(max_length=200)
slug = models.SlugField()
texto = models.TextField("Texto da noticia")
class Meta:
ordering = ['-data_publicacao']
get_latest_by = 'data_publicacao'
def __unicode__(self):
return self.titulo
Como esperado, o código acima vai gerar um tabela no banco, mas, para a busca funcionar corretamente, teremos que criar "no braço" um índice fulltext para efetuar a busca. Como estamos utilizando o mecanismo de busca do próprio banco. O índice será atualizado automaticamente quando registros são inseridos, atualizados, ou excluídos, de modo que os resultados da pesquisa nunca estarão desatualizada. A declaração CREATE INDEX é utilizado para criar o índice:
CREATE FULLTEXT INDEX fti_noticias_artigo ON noticias_artigo(titulo,texto)
Bom agora teremos que estender esta funcionalidade ao ORM do Django e criar um manager para o model em que você quer fazer a busca. Para isso simplesmente copie este código no seu models, ou melhor, coloque em um arquivos separado, já que você poderá aproveitá-lo em outros models!
Agora, chame o manager do código, atribuindo ao atributo objects (ou qualquer outro que você criar) passando como parâmetro os campos que você indexou no mysql:
objects = SearchManager(('titulo', 'texto'))e está pronto!
agora para realizar alguma busca utilize o seguinte comando:
Artigo.objects.search('minha busca')o método search executará uma consulta, verificando se a string que você enviou se encontra em um dos campos que você estabeleceu no seu SearchManager.
algo mais ou menos assim:
SELECT titulo, data_publicacao, slug, texto, MATCH(titulo, texto) AGAINST ('minha busca')
AS `relevance`
FROM noticias_artigo
WHERE MATCH(titulo, texto) AGAINST ('minha busca')O seu manager também inclui um campo extra na sua consulta chamado relevance, que é o indice de relevância da sua pesquisa. Desse modo é possivel efetuar uma ordenacão através deste campo.
Artigo.objects.search('minha busca').order_by('relevance')bom era isso! qualquer duvida, reclamação, ou colaboração de código, é só comentar!






