PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Tạo Chỉ mục Gin với Trigram (gin_trgm_ops) trong mô hình Django

Tôi đã tìm thấy một 12/2020 bài viết sử dụng phiên bản mới nhất của Django ORM, chẳng hạn như:

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

Nếu, giống như người đăng ban đầu, bạn đang muốn tạo một chỉ mục hoạt động với icontains, bạn sẽ phải lập chỉ mục UPPER () của cột, yêu cầu xử lý đặc biệt từ 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',
            )
        ]

Lấy cảm hứng từ bài viết cũ về chủ đề này, tôi đã đến hiện tại cung cấp giải pháp sau cho GistIndex :

Cập nhật:Từ Django-1.11, mọi thứ dường như đơn giản hơn, vì câu trả lời này tài liệu django nhiều đường nhất:

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

Từ Django-2.2 , một thuộc tính opclasses sẽ có sẵn trong lớp class Index(fields=(), name=None, db_tablespace=None, opclasses=()) cho mục đích này.

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

Sau đó, bạn có thể sử dụng cái nào trong lớp mô hình của mình như sau:

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. Đổi tên nhiều cột trong một câu lệnh với PostgreSQL

  2. Cách tạo ràng buộc loại trừ với phạm vi ngày sử dụng sqlalchemy

  3. PostgreSQL Replication để phục hồi sau thảm họa

  4. Tạo chuỗi khoảng thời gian trong tuần cho tháng nhất định

  5. GROUP hoặc DISTINCT sau khi JOIN trả về các bản sao