PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Tworzenie indeksu Gin z Trigramem (gin_trgm_ops) w modelu Django

Znalazłem artykuł 12/2020 który używa najnowszej wersji Django ORM jako takiej:

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'],
            )
        ]

Jeśli, tak jak oryginalny plakat, chciałeś utworzyć indeks, który działa z ikonami, będziesz musiał zaindeksować UPPER() kolumny, co wymaga specjalnej obsługi ze strony 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',
            )
        ]

Zainspirowany stary artykuł na ten temat trafiłem do aktualny co daje następujące rozwiązanie dla GistIndex :

Aktualizacja:Z Django-1.11 wszystko wydaje się prostsze, ponieważ ta odpowiedź i dokumentacja django sugestia:

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'])]

Od Django-2.2 , atrybut opclasses będzie dostępny w klasie class Index(fields=(), name=None, db_tablespace=None, opclasses=()) w tym celu.

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

Które następnie możesz użyć w swojej klasie modelu w następujący sposób:

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

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak najlepiej wykorzystać logi PostgreSQL

  2. SQLite do Postgres (Heroku) GROUP BY

  3. Jak rozwiązać problem z uprawnieniami podczas uruchamiania Postgresql z minikube?

  4. SQL:Odwróć transponowanie tabeli

  5. Kolejka w php i postgres