Полнотекстовый поиск в Django

django full text search Для простого поиска в Django обычно хватает стандартного Q-объекта с индексом по поисковым полям. Но иногда нужны более серьезные возможности поиска, например, ранжирование, морфологический поиск, n-gram'ы, фасетная классификация, проверка синтаксиса и т.д., многое из перечисленного поддерживают в той или иной степени Sphinx, Xapian, Solr, Whoosh.

Каждый из перечисленных вариантов хорош в своем случаи, где какой применять зависит от навыков и фантазии разработчика. Сравнительный обзор некоторых решений есть тут. На страницах документации Haystack есть таблица с списком возможностей разных поисковых бэкендов и реализованными возможностями в haystack (прослойке между django и поисковыми бэкендами).

На stackoverflow.com есть тестирование скорости индексирования и поиска в sphinx и xapian.

High Performance FullText Search - презентация с сравнением некоторых полнотекстовых поисковых движков.

Встроенные средства Django

Q objects

Для начала коротко про Q-объекты, которые не относятся к полнотекстовому поиску, но не все знают как их готовить.

Поиск с объединением через И (AND)

from django.db.models import Q
Products.objects.filter(Q(title__icontains=title) & Q(category=cat))

Поиск с объединением через ИЛИ (OR)

Products.objects.filter(Q(title__icontains=title) | Q(category=cat))

Поиск с объединением через И (AND) и исключением по одному из полей

Products.objects.filter(Q(title__icontains=title) | ~Q(category=cat))

Поиск с динамически добавляемыми критериями поиска

import operator
criterions = [Q(title__icontains=title),]
criterions.append(Q(category=cat))
Products.objects.filter(reduce(operator.or_, criterions))

Также можно использовать operator.and_ для операции AND.

Еще один вариант объединения критериев

from django.db.models import Q
criterions = Q(title__icontains=title)
criterions.add(Q(category=cat), Q.OR)
Products.objects.filter(criterions)

Надстройка над MySQL

Если у поля есть полнотекстовый индекс, то можно искать с указанием что включить в поиск, а что нет

products = Products.objects.filter(title__search='+майка -красная')

Для создания полнотекстового индекса нужно выполнить такую mysql-команду:

CREATE FULLTEXT INDEX title_idx ON products_product (title);

Этот вариант поиска работает только с таблицами типа MyISAM с полями типа CHAR, VARCHAR, и TEXT.

Xapian

Sphinx

Индексы:

Whoosh

Дополнительное чтиво

Теги: Django, MySQL, Sphinx, Whoosh, Xapian

blog comments powered by Disqus