Выделение основ слов и ранжирование результатов
Выделение основы слова, или стемминг, это процесс приведения слов к их словообразовательной базе, основанию или корневой форме.
Стемминг используется поисковыми системами для редуцирования индексированных слов до их основы и для того, чтобы иметь возможность сопоставлять изменяемые или производные слова. Например, слова music, musical и musicality поисковая система может считать похожими словами.
В процессе выделения основы каждый поисковый токен нормализуется в лексему, или единицу лексического значения, которая лежит в основе набора слов, связанных посредством флексии. При создании поискового запроса слова music, musical и musicality будут преобразованы в music.
Django предоставляет класс SearchQuery, чтобы транслировать термины в объект поискового запроса. По умолчанию термины пропускаются через базовые алгоритмы выделения основ слов, что помогает получать более оптимальные совпадения.
Поисковый механизм PostgreSQL также удаляет стоп-слова, такие как a, the, on и of.
Стоп-слова – это коллекция часто используемых слов в языке. Они удаляются при создании поискового запроса, поскольку появляются слишком часто, чтобы быть релевантными для поисковых запросов.
Список стоп-слов, используемых PostgreSQL для английского языка, находится на странице https://github.com/postgres/postgres/blob/master/src/backend/snow-ball/stopwords/english.stop.
Мы также хотим упорядочивать результаты по релевантности. PostgreSQL предоставляет функцию ранжирования, которая упорядочивает результаты на основе частоты появления терминов запроса и степени их близости друг к другу.
Отредактируйте файл views.py приложения blog, добавив следующую ниже инструкцию импорта:
from django.contrib.postgres.search import SearchVector, SearchQuery, SearchRank
Затем отредактируйте представление 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', 'body')
search_query = SearchQuery(query)
results = Post.published.annotate(
search=search_vector,
rank=SearchRank(search_vector, search_query)
).filter(search=search_query).order_by('-rank')
return render(request,
'blog/post/search.html',
{'form': form,
'query': query,
'results': results})
В приведенном выше исходном коде создается объект SearchQuery, по нему фильтруются результаты, и для упорядочивания результатов по релевантности используется SearchRank.
Теперь можно перейти по адресу http://127.0.0.1:8000/blog/search/ в своем браузере и протестировать различные поисковые запросы, чтобы проверить выделение основ слов и ранжирование.
Ниже приведен пример ранжирования по числу появлений слова django в заголовке и теле постов:
Выделение основ слов и удаление стоп-слов на разных языках
Объекты SearchVector и SearchQuery можно настроить под исполнение процедур выделения основ слов и удаления стоп-слов на любом языке.
Для того чтобы использовать другую конфигурацию поиска, в SearchVector и SearchQuery передается атрибут config.
Такой подход позволяет использовать разные языковые парсеры и словари.
В следующем ниже примере выделяются основы слов и удаляются стоп-слова на русском языке:
search_vector = SearchVector('title', 'body', config='russian')
search_query = SearchQuery(query, config='russian')
results = Post.published.annotate(
search=search_vector,
rank=SearchRank(search_vector, search_query)
).filter(search=search_query).order_by('-rank')
Используемый в PostgreSQL словарь русских стоп-слов находится на странице https://github.com/postgres/postgres/blob/master/src/backend/snowball/stopwords/russian.stop
Все языки можете посмотреть по ссылке - https://github.com/postgres/postgres/tree/master/src/backend/snowball/stopwords