Vi undersøgte mere grundigt forstået, hvordan søgning virker vægte.
Ifølge dokumenter du kan tildeles vægte i henhold til felterne, og de kan endda tildeles vægte, og på samme måde kan vi bruge trigrammer at filtrere efter lighed eller afstand.
Angiv dog ikke et eksempel på at bruge de to og undersøge nærmere, det forstås heller ikke meget, da vægte virker.
En lille logik fortæller os, at hvis vi søger et fælles ord i alt, vil vi alle rangere 0, lighed varierer meget mere end områder, men har en tendens til at sænke værdier i dette område.
Nu, tekstsøgning, så vidt vi forstår, udføres den baseret på teksten indeholdt i de felter, du ønsker at filtrere endnu mere end på det sprog, der er placeret i konfigurationen. Eksempel er, at ved at sætte titler, den brugte model havde et titelfelt og et indholdsfelt, hvis mest almindelige ord var how change
, gennemgang af vægtede ord (intervaller fungerer som forespørgsel, så vi kan bruge values
eller values_list
for at gennemgå rækkerne og lighederne, som er numeriske værdier, kan vi se vægtede ord, der ser vektorobjekt), så vi, at hvis vægte blev tildelt, men kombinationer af opdelte ord:fundet 'perfil' og 'cambi', men vi fandt ikke 'cambiar' eller 'como'; dog havde alle modeller indeholdt den samme tekst som 'lorem ipsun ...', og alle ordene i den sætning, hvis de var hele og med vægt B; Vi konkluderer med dette, at søgningerne udføres baseret på indholdet af felterne for at filtrere mere end det sprog, som vi konfigurerer søgninger med.
Når det er sagt, præsenterer vi her den kode, vi bruger til alt.
Først skal vi bruge Trigrammer i det omfang, det er nødvendigt for at aktivere databasen:
from django.db import migrations
from django.contrib.postgres.operations import UnaccentExtension, TrigramExtension
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
...
TrigramExtension(),
UnaccentExtension(),
]
Importer handlinger til migrering fra postgres
pakker og køre fra enhver filmigrering .
Det næste trin er at ændre koden for spørgsmålet, så filteret returnerer en af forespørgslerne, hvis den anden mislykkes:
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 ovenstående kode var at sive den ene forespørgsel efter den anden, og hvis det valgte ord ikke optræder i nogen af de to søgninger, er problemet større. Vi bruger en Q
objekt at filtrere ved hjælp af en OR
stik, så hvis en af de to ikke returnerer en ønsket værdi, så send den anden på plads.
Med dette er nok, men de er velkomne forklaringer på, hvordan disse vægte og trigrammer fungerer, for at få mest muligt ud af denne nye fordel, som den seneste version af Django tilbyder.