如何使用 Django 功能而不是所有键来索引刚刚选择的 json 键?
Posted
技术标签:
【中文标题】如何使用 Django 功能而不是所有键来索引刚刚选择的 json 键?【英文标题】:How to index just selected json key using Django functionality instead of all keys? 【发布时间】:2020-04-14 18:57:10 【问题描述】:我有下一个模型:
from django.contrib.postgres.fields import JSONField
from django.contrib.postgres.fields.jsonb import KeyTextTransform
from django.contrib.postgres.indexes import GinIndex
from django.contrib.postgres.search import SearchVectorField, SearchVector
from django.db import models
class ProfileUser(models.Model):
name = JSONField()
search_vector = SearchVectorField(null=True)
class Meta:
indexes = [GinIndex(fields=["search_vector"], name="user_full_name_gin_idx")]
def save(self, *args, **kwargs):
super(ProfileUser, self).save(*args, **kwargs)
ProfileUser.objects.filter(pk=self.pk).update(search_vector=SearchVector('name'))
# I have tried this, but this does not work.
# ProfileUser.objects.filter(pk=self.pk).update(search_vector=SearchVector(KeyTextTransform('name', 'name')))
而name
看起来像['name': 'Random Name', 'lang': 'en', 'name': 'Какое-то Имя', 'lang': 'ru']
。
目前上面的代码索引name
和lang
键。是否可以使用 Django 仅索引 name
键?我found 如何直接使用 SQL 来解决这个问题,但我只想知道,是否可以通过 Django 来解决。
我使用 Django 2.2 和 PostgreSQL 12。
【问题讨论】:
【参考方案1】:在 PostgreSQL 中,允许在部分 JSON 结构字段上创建索引的功能称为 expression index。它需要与GIN
索引一起使用才能达到预期的效果。这样的用法在jsonb
documentation中有简单的提及:
CREATE INDEX idxgintags ON api USING GIN ((jdoc -> 'tags'));
据我所知,目前(2020 年 12 月)在 Django 中创建此类索引的唯一方法是手动发出 SQL 语句。
但是,有一个开放的ticket 要求向 Django 添加对表达式索引的支持。该功能已被接受,但还没有补丁,并且一年多没有更新票证。
【讨论】:
在此 PR 的 3.2 中添加了支持:github.com/django/django/pull/11929 但是,我仍然对正确的语法感到困惑。【参考方案2】:Functional indexes 将于 4 月在 Django 3.2 中可用。这最终应该允许从 Django 构建所需的索引。
【讨论】:
【参考方案3】:是的,有可能,您可以在此处阅读 django 索引文档: https://docs.djangoproject.com/en/3.0/ref/models/indexes/
改变这一行:
indexes = [GinIndex(fields=["search_vector"], name="user_full_name_gin_idx")]
到这里:
indexes = [GinIndex(fields=["name"], name="user_full_name_gin_idx")]
【讨论】:
这无济于事,因为fields=["name"]
包含两个字段(name
和lang
)。 fields
表示 field names of model
(不是 JSON 的键)。以上是关于如何使用 Django 功能而不是所有键来索引刚刚选择的 json 键?的主要内容,如果未能解决你的问题,请参考以下文章
django css 不会从索引 url 而不是任何其他 url 加载
Django ORM:如何根据所有记录中的列获取唯一记录(需要模型对象而不是特定值对象)