Ik heb een 12/2020-artikel gevonden die de nieuwste versie van Django ORM als zodanig gebruikt:
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'],
)
]
Als je, net als de originele poster, een index wilde maken die werkt met icontains, dan moet je de UPPER() van de kolom indexeren, wat een speciale behandeling vereist van 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',
)
]
Geïnspireerd door een oud artikel
over dit onderwerp kwam ik terecht bij een huidige
wat de volgende oplossing geeft voor een GistIndex
:
Update:Vanaf Django-1.11 lijken dingen eenvoudiger te zijn, zoals dit antwoord en django-documenten stel voor:
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'])]
Van Django-2.2 , een attribuut opclasses
zal beschikbaar zijn in de class Index(fields=(), name=None, db_tablespace=None, opclasses=())
voor dit doel.
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
Die je dan als volgt in je modelklasse kunt gebruiken:
class YourModel(models.Model):
some_field = models.TextField(...)
class Meta:
indexes = [
GistIndexTrgrmOps(fields=['some_field'])
]