Abbiamo studiato in modo più approfondito il modo in cui la ricerca funziona con i pesi.
Secondo documents è possibile assegnare pesi in base ai campi e possono anche essere assegnati pesi, e allo stesso modo si può usare trigrams per filtrare per similarità o distanza.
Tuttavia, non specificare un esempio di utilizzo dei due e di indagare ulteriormente, né tanto meno come funzionano i pesi.
Un po 'di logica ci dice che se cerchiamo una parola comune in tutti noi tutti i gradi 0, la somiglianza varia molto di più degli intervalli, tuttavia tende a valori più bassi che variano.
Ora, la ricerca di testo, per quanto ne sappiamo, viene eseguita in base al testo contenuto nei campi che si desidera filtrare ancor più che nella lingua che viene inserita nella configurazione. L'esempio è che mettendo i titoli, il modello usato aveva un campo titolo e un campo contenuto, le cui parole più comuni erano how change
, rivedendo parole ponderate (gli intervalli funzionano come query, quindi possiamo usare values
o values_list
per rivedere i ranghi e le somiglianze, che sono valori numerici, possiamo vedere le parole ponderate che guardano oggetto vettoriale), abbiamo visto che se i pesi venivano assegnati, ma le combinazioni di parole suddivise: trovato 'perfil' e 'cambi', tuttavia non abbiamo trovato 'cambiar' o 'como' ; tuttavia, tutti i modelli contenevano lo stesso testo di "lorem ipsun ..." e tutte le parole di quella frase se erano complete e con i pesi B; Concludiamo dicendo che le ricerche vengono eseguite in base al contenuto dei campi per filtrare più della lingua con cui configuriamo le ricerche.
Detto questo, qui vi presentiamo il codice che usiamo per tutto.
In primo luogo, abbiamo bisogno di usare trigrammi nella misura necessaria per abilitare il database: operazioni
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
from django.contrib.postgres.operations import UnaccentExtension
from django.contrib.postgres.operations import TrigramExtension
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
...
TrigramExtension(),
UnaccentExtension(),
]
Importa per la migrazione da postgres
pacchetti ed eseguire la migrazione da qualsiasi file.
Il passo successivo è quello di modificare il codice della questione in modo che il filtro restituisce uno dei querys se il secondo fallisce:
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
) + TrigramSimilarity(
'content', search
),
).filter(Q(rank__gte=0.3) | Q(similarity__gt=0.3)).order_by('-rank')[:20]
Il problema con il codice di cui sopra filtrava una query dopo l'altro, e se la parola scelta non appare in nessuna delle due ricerche il problema è maggiore. Utilizziamo un oggetto Q
per filtrare utilizzando un connettore OR
in modo che se uno dei due non restituisce un valore desiderato, inviare l'altro sul posto.
Con questo è sufficiente, tuttavia sono graditi chiarimenti approfonditi su come funzionano questi pesi e trigrammi, per sfruttare al meglio questo nuovo vantaggio offerto dall'ultima versione di Django.
Grazie per aver condiviso la soluzione trovata. – Private