如何在 Django 1.9 中查询复杂的 JSONB 字段

Posted

技术标签:

【中文标题】如何在 Django 1.9 中查询复杂的 JSONB 字段【英文标题】:How do I query a complex JSONB field in Django 1.9 【发布时间】:2017-02-05 12:10:34 【问题描述】:

我有一个表 item,其中有一个名为 data 的 JSONB 类型的字段。我想查询所有文本等于“超级”的项目。我目前正在尝试这样做:

Item.objects.filter(Q(data__areas__texts__text='Super'))

Django 调试工具栏报告用于此的查询是:

WHERE "item"."data" #> ARRAY['areas', 'texts', 'text'] = '"Super"'

但我没有得到任何匹配的结果。如何使用 Django 进行查询?如果在 Django 中不可能,那么如何在 Postgresql 中查询呢?

以下是data 字段内容的示例:


  "areas": [
    
      "texts": [
        
          "text": "Super"
        
      ]
    ,
    
      "texts": [
        
          "text": "Duper"
        
      ]
    
  ]

【问题讨论】:

【参考方案1】:

试试Item.objects.filter(data__areas__0__texts__0__text='Super')

这不是确切的答案,但它可以澄清一些 jsonb 过滤器功能,另请阅读django docs

我不确定你想用这种结构实现什么,但我只能通过奇怪的原始查询获得所需的结果,它可能看起来像这样:

Item.objects.raw("SELECT id, data FROM (SELECT id, data, jsonb_array_elements(\"table_name\".\"data\" #> 'areas') as areas_data from \"table_name\") foo WHERE areas_data #> 'texts' @> '[\"text\": \"Super\"]'")

不要忘记在查询中更改table_name(在您的情况下应该是yourappname_item)。

不确定您是否可以在实际程序中使用此查询,但它可能可以帮助您找到更好的解决方案。

另外,there is 非常好的 jsonb 查询语法介绍

希望对你有帮助

【讨论】:

Item.objects.filter(data__areas__0__texts__0__text='Super') 确实有效,但不是我想要的,因为我希望它搜索数组的每个元素。原始查询是我正在寻找的,所以谢谢。不幸的是,我不能使用 Django 做到这一点,但如果汽车可以自动驾驶,那么我认为有希望 ;) 汽车仍然无法自行驾驶,但有一篇很棒的博客文章展示了如何以“Django 方式”使用jsonb_array_elements:blog.qax.io/django-and-postgres-jsonb-field-beyond-the-basics,这似乎并不过时。

以上是关于如何在 Django 1.9 中查询复杂的 JSONB 字段的主要内容,如果未能解决你的问题,请参考以下文章

Django 1.9 在列表中查找属性等于某个值的对象

如何在 Django 1.9 中传递可调用对象

如何在 django 1.9+ 中合并连续的数据库迁移?

如何在 django 1.9 中删除 django-admin 中的保存并继续编辑按钮,使其不存在?

如何在 Django 1.9 中删除 DB (sqlite3) 以从头开始?

如何在 Django 1.9 中表达 sqlite LEFT OUTER JOIN?