Проучихме по-задълбочено, за да разберем как търсенето работи с тежести.
Според документи могат да ви бъдат присвоени тегла според полетата и те дори могат да бъдат присвоени тегла и по подобен начин можем да използваме триграми за филтриране по сходство или разстояние.
Въпреки това не посочвайте пример за използване на двете и по-нататъшно разследване, което е разбрало, нито много как теглата работят.
Малко логика ни казва, че ако търсим обща дума във всички, всички ще се класираме на 0, сходството варира много повече от диапазоните, но има тенденция към по-ниски стойности в този диапазон.
Сега търсенето на текст, доколкото разбираме, се извършва въз основа на текста, съдържащ се в полетата, които искате да филтрирате дори повече, отколкото на езика, който е поставен в конфигурацията. Пример е, че поставяйки заглавия, използваният модел имаше поле за заглавие и поле за съдържание, чиито най-често срещани думи бяха how change
, преглед на претеглени думи (диапазоните функционират като заявка, така че можем да използваме values
или values_list
за преглед на ранговете и приликите, които са числени стойности, можем да преглеждаме претеглени думи, преглеждайки векторен обект), видяхме, че ако са разпределени тегла, но комбинации от разделени думи:намерени „perfil“ и „cambi“, но не намерихме „cambiar“ или „como“; въпреки това, всички модели са съдържали същия текст като „lorem ipsun ...“ и всички думи от това изречение, ако са били цели и с тегла B; С това заключаваме, че търсенията се извършват въз основа на съдържанието на полетата, за да филтрират повече от езика, с който конфигурираме търсенията.
Въпреки това, тук представяме кода, който използваме за всичко.
Първо, трябва да използваме Trigrams в необходимата степен, за да активираме базата данни:
from django.db import migrations
from django.contrib.postgres.operations import UnaccentExtension, TrigramExtension
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
...
TrigramExtension(),
UnaccentExtension(),
]
Операции за импортиране за мигриране от postgres
пакети и стартирайте от всяка миграция на файлове .
Следващата стъпка е да промените кода на въпроса, така че филтърът да върне една от заявките, ако втората е неуспешна:
def get_queryset(self):
search_query = SearchQuery(self.request.GET.get('q', ''))
vector = SearchVector(
'name',
weight='A',
config=settings.SEARCH_LANGS[settings.LANGUAGE_CODE],
) + SearchVector(
'content',
weight='B',
config=settings.SEARCH_LANGS[settings.LANGUAGE_CODE],
)
if self.request.user.is_authenticated:
queryset = Article.actives.all()
else:
queryset = Article.publics.all()
return queryset.annotate(
rank=SearchRank(vector, search_query)
similarity=TrigramSimilarity(
'name', search_query
) + TrigramSimilarity(
'content', search_query
),
).filter(Q(rank__gte=0.3) | Q(similarity__gt=0.3)).order_by('-rank')[:20]
Проблемът с горния код беше преминаването на една заявка след друга и ако избраната дума не се появи в нито едно от двете търсения, проблемът е по-голям. Използваме Q
обект за филтриране чрез OR
конектор, така че ако едно от двете не върне желана стойност, да изпрати другото на място.
С това е достатъчно, но са добре дошли задълбочени разяснения за това как работят тези тежести и триграми, за да изяснят максимално това ново предимство, предлагано от най-новата версия на Django.