experimental map
[wolnelektury.git] / src / search / utils.py
1 from django.db.models import Func
2 from django.contrib.postgres.search import SearchQuery, SearchVectorField
3
4
5 class UnaccentSearchQuery(SearchQuery):
6     '''
7     The idea is to run unaccent *after* the query is already passed through the language dictionary.
8     '''
9     def as_sql(self, *args, **kwargs):
10         sql, params = super().as_sql(*args, **kwargs)
11         sql = f'unaccent({sql}::text)::tsquery'
12         return sql, params
13
14
15 class UnaccentSearchVector(Func):
16     '''
17     We do the indexing twice, to account for non-diacritic versions.
18     For example: user enters 'róże' -> stem to 'róża' -> unaccent to 'roza'.
19     But user enters 'roze' -> stem leaves it as is, so we need original form in the vector.
20     '''
21     function='to_tsvector'
22     template = '''unaccent(
23       %(function)s('polish', %(expressions)s)::text)::tsvector ||
24      to_tsvector(
25        'polish_simple', 
26        unaccent(%(expressions)s)
27      )'''
28     output_field = SearchVectorField()