dar*_*rse 16 django postgresql
我正在使用一个简单的模型,该模型的属性将该对象的所有数据存储在 JSONField 中。将其视为将 NoSQL 数据传输到我的 PostgreSQL 数据库的方式。有点像这样:
from django.contrib.postgres.fields import JSONField
class Document(models.Model):
content = JSONField()
Run Code Online (Sandbox Code Playgroud)
每个Document对象在其content字段中(或多或少)具有相同的键,因此我正在使用这些键查询和排序这些文档。对于查询和排序,我使用的是 Django 的annotate()函数。我最近遇到了这个:
https://docs.djangoproject.com/en/2.1/ref/contrib/postgres/indexes/
我也知道 PostgreSQL 使用 JSONB,这显然是可索引的。所以我的问题是:我能否content以某种方式索引我的字段以加快复杂查询的读取操作?如果是这样,那么我该怎么做?我链接的文档页面没有示例。
kco*_*ntr 17
正如Tim Tisdall在另一个答案中评论的那样,Django 3.2 引入了对这些索引的本机支持。如果您要将这些添加到现有模型中,请务必添加makemigrations和migrate。
要索引特定键,您可以将F 表达式与模型的 Meta选项上的JSONField 路径查找相结合:indexes
from django.contrib.postgres.fields import JSONField
class Document(models.Model):
content = JSONField()
class Meta:
indexes = [
models.Index(models.F("content__example_field_name"), name="content__example_field_name_idx"),
]
Run Code Online (Sandbox Code Playgroud)
如果您想使用过滤器,例如has_key在顶级字段上(例如Document.objects.filter(content__has_key="example_field_name")),您可能需要像Mahesh H Viraktamath在另一条评论中建议的那样GinIndex。
from django.contrib.postgres.fields import JSONField
from django.contrib.postgres.indexes import GinIndex
class Document(models.Model):
content = JSONField()
class Meta:
indexes = [
GinIndex("content", name="content_idx"),
]
Run Code Online (Sandbox Code Playgroud)
最后,为了完整起见,您可以通过用表达式包装来选择您的 opclass 。OpClass
from django.contrib.postgres.fields import JSONField
from django.contrib.postgres.indexes import GinIndex, OpClass
class Document(models.Model):
content = JSONField()
class Meta:
indexes = [
GinIndex(
OpClass(models.F("content__example_field_name"), name="jsonb_path_ops"),
name="content__example_field_name_idx",
),
]
Run Code Online (Sandbox Code Playgroud)
对于那些想要索引特定键的人,创建一个原始的 sql 迁移:
运行您要为其更改索引的模型的应用程序./manage.py makemigrations --empty yourApp所在的位置yourApp。
编辑迁移即
operations = [
migrations.RunSQL("CREATE INDEX idx_name ON your_table((json_field->>'json_key'));")
]
Run Code Online (Sandbox Code Playgroud)
哪里idx_name是索引的名称,your_table是你的表,json_field是你的 JSONField,json_key在这种情况下是你想要索引的键。
应该可以,但要验证一切顺利,请运行以下 sql:
SELECT
indexname,
indexdef
FROM
pg_indexes
WHERE
tablename = '<your-table>';
Run Code Online (Sandbox Code Playgroud)
看看你的索引是否在那里。
| 归档时间: |
|
| 查看次数: |
3083 次 |
| 最近记录: |