sql >> Databáze >  >> RDS >> PostgreSQL

Vytvoření indexu Gin pomocí Trigramu (gin_trgm_ops) v modelu Django

Našel jsem článek z 12/2020 která používá nejnovější verzi Django ORM jako takovou:

class Author(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)

    class Meta:
        indexes = [
            GinIndex(
                name='review_author_ln_gin_idx', 
                fields=['last_name'], 
                opclasses=['gin_trgm_ops'],
            )
        ]

Pokud jste stejně jako původní plakát chtěli vytvořit rejstřík, který by pracoval s icontains, budete muset indexovat UPPER() sloupce, což vyžaduje speciální zpracování od OpClass :

from django.db.models.functions import Upper
from django.contrib.postgres.indexes import GinIndex, OpClass

class Author(models.Model):
        indexes = [
            GinIndex(
                OpClass(Upper('last_name'), name='gin_trgm_ops'),
                name='review_author_ln_gin_idx',
            )
        ]

Inspirováno starým článkem na toto téma jsem přistál na aktuální což poskytuje následující řešení pro GistIndex :

Aktualizace:Od Django-1.11 se věci zdají být jednodušší, jak uvádí tato odpověď a django docs navrhněte:

from django.contrib.postgres.indexes import GinIndex

class MyModel(models.Model):
    the_field = models.CharField(max_length=512, db_index=True)

    class Meta:
        indexes = [GinIndex(fields=['the_field'])]

Z Django-2.2 , atribut opclasses bude k dispozici ve třídě class Index(fields=(), name=None, db_tablespace=None, opclasses=()) pro tento účel.

from django.contrib.postgres.indexes import GistIndex

class GistIndexTrgrmOps(GistIndex):
    def create_sql(self, model, schema_editor):
        # - this Statement is instantiated by the _create_index_sql()
        #   method of django.db.backends.base.schema.BaseDatabaseSchemaEditor.
        #   using sql_create_index template from
        #   django.db.backends.postgresql.schema.DatabaseSchemaEditor
        # - the template has original value:
        #   "CREATE INDEX %(name)s ON %(table)s%(using)s (%(columns)s)%(extra)s"
        statement = super().create_sql(model, schema_editor)
        # - however, we want to use a GIST index to accelerate trigram
        #   matching, so we want to add the gist_trgm_ops index operator
        #   class
        # - so we replace the template with:
        #   "CREATE INDEX %(name)s ON %(table)s%(using)s (%(columns)s gist_trgrm_ops)%(extra)s"
        statement.template =\
            "CREATE INDEX %(name)s ON %(table)s%(using)s (%(columns)s gist_trgm_ops)%(extra)s"

        return statement

Které pak můžete použít ve své modelové třídě takto:

class YourModel(models.Model):
    some_field = models.TextField(...)

    class Meta:
        indexes = [
            GistIndexTrgrmOps(fields=['some_field'])
        ]


  1. Kontrola více sloupců pro jednu hodnotu

  2. nahrání více obrázků nesprávné množství při nahrání souboru

  3. Jak načíst data z kurzoru v Oracle pomocí For Loop

  4. Má PostgreSQL pseudosloupec jako LEVEL v Oracle?