Vi undersökte mer ingående och förstod hur sökning fungerar vikter.
Enligt dokument du kan tilldelas vikter enligt fälten och de kan till och med tilldelas vikter, och på samma sätt kan vi använda trigram för att filtrera efter likhet eller avstånd.
Men inte specificera ett exempel på att använda de två och undersöka vidare det förstod inte heller mycket som vikter fungerar.
Lite logik säger oss att om vi söker ett gemensamt ord i alla kommer vi alla att rankas 0, likhet varierar mycket mer än intervall, men tenderar att sänka värden som intervall.
Nu, textsökning, så vitt vi förstår, utförs den baserat på texten som finns i fälten du vill filtrera ännu mer än på språket som är placerat i konfigurationen. Exempel är att sätta titlar, den använda modellen hade ett titelfält och ett innehållsfält, vars vanligaste ord var how change
, granska viktade ord (intervall fungerar som fråga, så vi kan använda values
eller values_list
för att granska rangordningen och likheterna, som är numeriska värden, kan vi se viktade ord som tittar på vektorobjekt), såg vi att om vikter tilldelades, men kombinationer av delade ord:hittade 'perfil' och 'cambi', men vi hittade inte 'cambiar' eller 'como'; dock hade alla modeller innehållit samma text som "lorem ipsun ...", och alla orden i den meningen om de var hela och med vikten B; Vi drar slutsatsen med detta att sökningarna görs baserat på innehållet i fälten för att filtrera mer än det språk som vi konfigurerar sökningar med.
Som sagt, här presenterar vi koden vi använder för allt.
Först måste vi använda Trigrams i den utsträckning som krävs för att aktivera databasen:
from django.db import migrations
from django.contrib.postgres.operations import UnaccentExtension, TrigramExtension
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
...
TrigramExtension(),
UnaccentExtension(),
]
Importera operationer för migrering från postgres
paket och körs från valfri filmigrering .
Nästa steg är att ändra koden för frågan så att filtret returnerar en av frågorna om den andra misslyckas:
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]
Problemet med ovanstående kod var att sippra en fråga efter en annan, och om det valda ordet inte förekommer i någon av de två sökningarna är problemet större . Vi använder en Q
objekt att filtrera med en OR
kontakt så att om en av de två inte returnerar ett önskat värde, skicka den andra på plats.
Med detta räcker det, men de är välkomna förtydliganden djupgående om hur dessa vikter och trigram fungerar, för att explitera det mesta av denna nya fördel som den senaste versionen av Django erbjuder.