You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Django PostgreSQL嵌套JSONField查询:匹配任意层级指定值

解决Django Postgres JSONField任意层级嵌套值的查询问题

嘿,这个问题我之前踩过坑!官方文档里的data__values__contains=['Melanie']确实搞不定多层嵌套的JSON结构——它只能遍历JSON顶层的value,没法深入到嵌套的数组或者对象里去搜索。下面给你两个靠谱的解决方案:

方案一:使用Django原生支持的JSON路径查询(推荐)

Postgres的JSON路径语法支持递归查找任意层级的内容,Django已经封装了对这个特性的支持。你可以通过__jsonpath查询条件来实现:

from django.db.models import Value

# 直接搜索指定值
Entity.objects.filter(data__jsonpath=Value('$[*]..name == "Melanie"'))

# 更灵活的参数化写法(避免硬编码)
target_name = "Melanie"
Entity.objects.filter(data__jsonpath=Value(f'$[*]..name == "{target_name}"'))

语法解释:

  • $代表整个JSON数据
  • [*]匹配数组中的所有元素
  • ..name递归查找所有层级下的name
  • == "Melanie"判断该键的值是否等于目标字符串

如果你的搜索不需要限定键名(比如要在整个JSON的任意位置找值),可以把路径改成$[*]..* == "Melanie",这样会匹配任意键下的目标值。

方案二:使用Raw SQL查询

如果对JSON路径语法不太熟悉,直接写Raw SQL也是个稳妥的选择,利用Postgres的jsonb_path_exists函数来判断:

target_value = "Melanie"
entities = Entity.objects.raw(
    """
    SELECT * FROM your_app_entity
    WHERE jsonb_path_exists(data, %s)
    """,
    [f'$[*]..name == "{target_value}"']
)

注意把your_app_entity替换成你实际的数据库表名(Django默认是应用名_模型名的小写形式,比如你的app叫myapp,表名就是myapp_entity)。

为什么官方的方法无效?

data__values__contains=['Melanie']的逻辑是提取JSON顶层所有value组成的集合,然后检查目标值是否在这个集合里。但你的data是嵌套的数组+对象结构,顶层value是一个个对象,不是字符串,所以这个方法自然找不到深层的Melanie

内容的提问来源于stack exchange,提问作者Paul R

火山引擎 最新活动