Используя Django и Postgres, у меня есть модель инвестиционного холдинга, такая как:
class Holding(BaseModel):
name = models.CharField(max_length=255, db_index=True)
symbol = models.CharField(max_length=16, db_index=True)
fund_codes = ArrayField(models.CharField(max_length=16), blank=True, default=list)
...
, которая содержит список из примерно 70 тыс. Долей США / CAN, взаимных фондов.Я хочу создать функцию автозаполнения поиска, которая расставляет приоритеты 1) ранжирование точного совпадения symbol
или fund_codes
, затем 2) близкие совпадения на symbol
, затем 3) полнотекстовый поиск удержания name
.
Если у меня есть вектор поиска, который добавляет больший вес к symbol
и fund_codes
:
from django.contrib.postgres.search import SearchVector, SearchQuery, SearchRank
from django.db.models import F, Func, Value
vector = SearchVector('name', weight='D') + \
SearchVector('symbol', weight='A') + \
SearchVector(Func(F('fund_codes'), Value(' '), function='array_to_string'), weight='A')
Затем, поиск 'MA'
Investment.objects \
.annotate(document=vector, rank=SearchRank(vector, query)) \
.filter(document__icontains='MA') \
.order_by('-rank') \
.values_list('name', 'fund_codes', 'symbol', 'rank',)
Не дает результатов, которые мне нужны.Мне нужна MA (Mastercard) в качестве верхнего списка, затем MAS (Masco Corp) и т.д. ... Затем списки, содержащие 'MA' в поле name
.
Я также посмотрел на переопределение SearchQuery
с:
class MySearchQuery(SearchQuery):
def as_sql(self, compiler, connection):
params = [self.value]
if self.config:
config_sql, config_params = compiler.compile(self.config)
template = 'to_tsquery({}::regconfig, %s)'.format(config_sql)
params = config_params + [self.value]
else:
template = 'to_tsquery(%s)'
if self.invert:
template = '!!({})'.format(template)
return template, params
Но все равно не получаю нужных мне результатов.Любые предложения о том, как я должен подходить к поисковой функциональности в этом случае использования?Возможно объединить точный поисковый запрос и полнотекстовый поисковый запрос?