sql >> Database >  >> RDS >> PostgreSQL

Combineer trigram met gerangschikt zoeken in django 1.10

We hebben een grondiger onderzoek gedaan naar hoe zoeken werkt met gewichten.

Volgens documenten er kunnen gewichten worden toegewezen volgens de velden en ze kunnen zelfs gewichten worden toegewezen, en op dezelfde manier kunnen we trigrammen om te filteren op gelijkenis of afstand.

Geef echter geen voorbeeld van het gebruik van de twee en onderzoek verder, het begreep ook niet zoveel als gewichten werken.

Een beetje logica vertelt ons dat als we een gemeenschappelijk woord zoeken in alle, we allemaal op 0 zullen staan, gelijkenis varieert veel meer dan bereiken, maar heeft de neiging om waarden in dat bereik te verlagen.

Nu wordt het zoeken naar tekst, voor zover we begrijpen, uitgevoerd op basis van de tekst in de velden die u wilt filteren, zelfs meer dan in de taal die in de configuratie is geplaatst. Voorbeeld is dat het zetten van titels, het gebruikte model een titelveld en een inhoudsveld had, waarvan de meest voorkomende woorden waren how change , het beoordelen van gewogen woorden (bereiken functioneren als query, dus we kunnen values gebruiken ​​of values_list om de rangen en overeenkomsten te bekijken, die numerieke waarden zijn, kunnen we gewogen woorden bekijken door vectorobjecten te bekijken), we zagen dat als gewichten werden toegewezen, maar combinaties van gesplitste woorden:'perfil' en 'cambi' gevonden, maar we hebben niet gevonden 'cambiar' of 'como'; alle modellen hadden echter dezelfde tekst als 'lorem ipsun ...', en alle woorden van die zin als ze heel waren en met gewichten B; We concluderen hiermee dat de zoekopdrachten worden gedaan op basis van de inhoud van de velden om meer te filteren dan de taal waarmee we zoekopdrachten configureren.

Dat gezegd hebbende, presenteren we hier de code die we voor alles gebruiken.

Eerst moeten we Trigrams gebruiken in de mate die nodig is om de database in te schakelen:

from django.db import migrations
from django.contrib.postgres.operations import UnaccentExtension, TrigramExtension

class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
      ...
      TrigramExtension(),
      UnaccentExtension(),

    ]

Importbewerkingen voor migratie van postgres pakketten en uitvoeren vanaf elke bestandsmigratie.

De volgende stap is om de code van de vraag te wijzigen, zodat het filter een van de zoekopdrachten retourneert als de tweede mislukt:

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]

Het probleem met de bovenstaande code was dat de ene zoekopdracht na de andere doorsijpelde, en als het gekozen woord niet in een van de twee zoekopdrachten voorkomt, is het probleem groter. We gebruiken een Q object om te filteren met een OR connector zodat als een van de twee niet de gewenste waarde retourneert, de andere op zijn plaats stuurt.

Hiermee is voldoende, maar ze zijn welkome verduidelijkingen over hoe deze gewichten en trigrama's werken, om het meeste uit dit nieuwe voordeel van de nieuwste versie van Django te halen.



  1. SQL-query die onderscheid maakt tussen ß en ss

  2. MySQL-query om resultaten te selecteren met automatische verhoging als een nieuwe kolom toegevoegd aan het resultaat

  3. Voeg een klein woordenboek in zoals {1:23, 2:45, 3:17} in een kolom van de SQL-databasetabel in Postgres met behulp van python-taal

  4. 1114 (HY000):De tafel is vol