You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django 3.2+MariaDB中JSONField嵌套数组对象查询无结果问题

解决Django 3.2 + MariaDB下JSONField嵌套数组的查询问题

问题原因

Django 3.2的JSONField ORM查询对嵌套数组的支持在MariaDB下存在局限性:默认的双下划线链式查询(如product_settings__resources__resource_config__...)无法自动遍历数组元素(需要明确指定数组通配符[*]),而MariaDB的JSON函数语法与PostgreSQL的jsonb操作不同,导致原查询无法匹配到目标数据。

可行解决方案

方案1:使用RawSQL直接执行MariaDB原生JSON查询

直接通过原生SQL调用MariaDB的JSON_SEARCH函数,精准定位嵌套数组中的目标值:

from django.db.models import RawSQL

# 替换yourapp_product为你的实际表名(app名+模型名小写)
products = Product.objects.raw('''
    SELECT * FROM yourapp_product
    WHERE JSON_SEARCH(product_settings, 'one', 'building', NULL, '$.resources[*].resource_config.linked_to.params.deposit.type') IS NOT NULL
''')
  • JSON_SEARCH参数说明:
    • 第一个参数:要查询的JSON字段
    • 'one':找到第一个匹配项即停止
    • 'building':要匹配的目标值
    • NULL:不限制路径前缀
    • 最后一个参数:完整的JSON路径,[*]表示遍历数组中的所有元素

方案2:使用Django Func表达式封装MariaDB JSON函数

通过Django的Func类封装JSON_CONTAINS函数,实现ORM风格的查询:

from django.db.models import Func, Value, BooleanField

class JSONContains(Func):
    function = 'JSON_CONTAINS'
    output_field = BooleanField()
    template = "%(function)s(%(field)s, %(value)s, %(path)s)"

products = Product.objects.filter(
    JSONContains(
        field='product_settings',
        value=Value('{"type": "building"}'),
        path=Value('$.resources[*].resource_config.linked_to.params.deposit')
    )
)
  • 此方法通过自定义Func类适配MariaDB的JSON_CONTAINS语法,检查指定路径下的JSON对象是否包含目标键值对。

注意事项

  • 确保你的MariaDB版本≥10.2,该版本开始完整支持JSON函数。
  • 若嵌套数组层级或结构有变动,需同步调整JSON路径中的[*]和节点名称。

内容的提问来源于stack exchange,提问作者Samuel Dauzon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 13:32:13