Взвешивание запросов
Влияние конкретных векторов можно усиливать таким образом, чтобы им придавался бóльший вес при упорядочивании результатов по релевантности. Например, взвешивание можно использовать, чтобы придавать большую релевантность постам, которые сочетаются по заголовку, а не по содержимому.
Отредактируйте файл views.py приложения blog, видоизменив представление post_search, как показано ниже:
def post_search(request):
form = SearchForm()
query = None
results = []
if 'query' in request.GET:
form = SearchForm(request.GET)
if form.is_valid():
query = form.cleaned_data['query']
search_vector = SearchVector('title', weight='A') + \
SearchVector('body', weight='B')
search_query = SearchQuery(query)
results = Post.published.annotate(rank=SearchRank(search_vector, search_query)
).filter(rank__gte=0.3).order_by('-rank')
return render(request,
'blog/post/search.html',
{'form': form,
'query': query,
'results': results})
В приведенном выше исходном коде к векторам поиска, сформированным с использованием полей title и body, применяются разные веса.
По умолчанию веса таковы: A, B, C, D и они относятся соответственно к числам 1.0, 0.4, 0.2, 0.1.
Вес 1.0 применяется к вектору поиска title(A), и вес 0.4 - к вектору body(B). Совпадения с заголовком будут преобладать над совпадениями с содержимым тела поста. Результаты фильтруются, чтобы отображать только те, у которых ранг выше 0.3.
Поиск по триграммному сходству
Еще одним подходом к поиску является триграммное сходство. Триграмма – это группа из трех следующих друг за другом символов. Сходство двух строковых литералов можно измерять, подсчитывая число общих для них триграмм. Во многих языках данный подход оказывается очень эффективным при измерении сходства слов.
Для того чтобы использовать триграммы в PostgreSQL, сначала необходимо установить расширение pg_trgm.
Запускаем SQL Shell чтобы подсоединиться к своей базе данных:
Затем исполните следующую ниже команду, чтобы установить расширение pg_trgm:
CREATE EXTENSION pg_trgm;
Вы получите такой результат:
CREATE EXTENSION
Давайте отредактируем представление и видоизменим его под триграммный поиск.
Отредактируйте файл views.py приложения blog, добавив следующую ниже инструкцию импорта:
from django.contrib.postgres.search import TrigramSimilarity
Затем видоизмените представление post_search, как показано ниже:
def post_search(request):
form = SearchForm()
query = None
results = []
if 'query' in request.GET:
form = SearchForm(request.GET)
if form.is_valid():
query = form.cleaned_data['query']
results = Post.published.annotate(
similarity=TrigramSimilarity('title', query),
).filter(similarity__gt=0.1).order_by('-similarity')
return render(request,
'blog/post/search.html',
{'form': form,
'query': query,
'results': results})
Пройдите по URL-адресу http://127.0.0.1:8000/blog/search/ в своем браузере и протестируйте различные варианты триграммного поиска.
В следующем ниже примере показана гипотетическая опечатка в термине django, показаны результаты поиска термина yango:
В приложение для ведения блога был добавлен мощный поисковый механизм.
Более подробная информация о полнотекстовом поиске находится на странице https://docs.djangoproject.com/en/5.0/ref/contrib/postgres/search/