如何使用新的 PostgreSQL JSON 数据类型中的字段进行查询?

Posted

技术标签:

【中文标题】如何使用新的 PostgreSQL JSON 数据类型中的字段进行查询?【英文标题】:How do I query using fields inside the new PostgreSQL JSON datatype? 【发布时间】:2012-05-20 14:00:17 【问题描述】:

我正在为 PostgreSQL 9.2 中的新 JSON 函数寻找一些文档和/或示例。

具体来说,给定一系列 JSON 记录:

[
  name: "Toby", occupation: "Software Engineer",
  name: "Zaphod", occupation: "Galactic President"
]

如何编写 SQL 来按名称查找记录?

在普通 SQL 中:

SELECT * from json_data WHERE "name" = "Toby"

官方的开发手册相当稀少:

http://www.postgresql.org/docs/devel/static/datatype-json.html http://www.postgresql.org/docs/devel/static/functions-json.html

更新我

我整理了一个gist detailing what is currently possible with PostgreSQL 9.2。 使用一些自定义函数,可以执行以下操作:

SELECT id, json_string(data,'name') FROM things
WHERE json_string(data,'name') LIKE 'G%';

更新二

我现在已将我的 JSON 函数移到他们自己的项目中:

PostSQL - 一组用于将 PostgreSQL 和 PL/v8 转换为非常棒的 JSON 文档存储的函数

【问题讨论】:

最近才发现Matt Schinckel的这篇博文,里面详细解释了在PostgreSQL中查询JSONschinckel.net/2014/05/25/querying-json-in-postgres @knowbody 这篇文章实际上是关于查询 JSONB 的,这与 JSON 截然不同。我很遗憾没有在帖子中说得更清楚。 【参考方案1】:

Postgres 9.2

我引用Andrew Dunstan on the pgsql-hackers list:

在某个阶段可能会有一些 json 处理(相反 生成 json) 函数,但在 9.2 中没有。

并不妨碍他在 PLV8 中提供一个可以解决您的问题的示例实现。 (链接已失效,请参阅现代版PLV8。)

Postgres 9.3

提供大量新函数和运算符以添加“json-processing”。

The manual on new JSON functionality. The Postgres Wiki on new features in pg 9.3。

Postgres 9.3 中原始问题的答案:

SELECT *
FROM   json_array_elements(
  '["name": "Toby", "occupation": "Software Engineer",
    "name": "Zaphod", "occupation": "Galactic President" ]'
  ) AS elem
WHERE elem->>'name' = 'Toby';

高级示例:

Query combinations with nested array of records in JSON datatype

对于较大的表,您可能需要添加表达式索引以提高性能:

Index for finding an element in a JSON array

Postgres 9.4

添加 jsonb(b 表示“二进制”,值存储为原生 Postgres 类型)以及 both 类型的更多功能。除了上面提到的表达式索引,jsonb 还支持GIN, btree and hash indexes,GIN 是其中最强大的。

json and jsonb data types 和 functions 的手册。 The Postgres Wiki on JSONB in pg 9.4

本手册建议:

一般来说,大多数应用程序应该更喜欢将 JSON 数据存储为 jsonb,除非有非常特殊的需求,比如遗留 关于对象键排序的假设。

我的大胆强调。

Performance benefits from general improvements to GIN indexes.

Postgres 9.5

完成jsonb 函数和运算符。添加更多函数来操作jsonb 并显示。

Major good news in the release notes of Postgres 9.5.

【讨论】:

谢谢,我使用 PLV8 方法很快就遇到了类型问题。看起来很有希望,但目前还不能真正使用。 @TobyHede:猜猜我们必须等到 9.3。 @JoeShaw:谢谢,我进行了相应更新并添加了指向 Postgres Wiki 的链接。 @ErwinBrandstetter 如果我正在寻找 WHERE elem->>'correct' = 'TRUE'; JSON看起来像这样:“正确”:“TRUE”,查询逻辑术语的正确方法是什么? @Shiraj:请以 question 的形式提出新问题。评论不是地方。【参考方案2】:

对于 Postgres 9.3+,只需使用 -> 运算符。例如,

SELECT data->'images'->'thumbnail'->'url' AS thumb FROM instagram;

请参阅http://clarkdave.net/2013/06/what-can-you-do-with-postgresql-and-json/ 获取一些不错的示例和教程。

【讨论】:

在上面的示例中,您应该有一个名为 data 的字段和一个 JSON 文档:images:thumbnail:url:'thumbnail.jpg'。让我们知道您的数据是什么样的以及哪些查询失败了。 ***.com/questions/22667401/… 如何查询是否有数组?我看到了 #>> 运算符,但不知道如何使用它! 在这个选择查询中我可以使用通配符吗?即SELECT data->'%'->'thumbnail'->'url' AS thumb FROM instagram; @Meekohi 的回答效果很好:特别是我不需要 ::json,如其他帖子中所述。另请注意,如果您尝试访问不存在的属性(即如果您有交错的 JSON),-> 运算符将引发错误:ERROR: column "jsonPropertyYouWant" does not exist【参考方案3】:

在 postgres 9.3 中使用 -> 进行对象访问。 4个例子

种子.rb

se = SmartElement.new
se.data = 

    params:
    [
        
            type: 1,
            code: 1,
            value: 2012,
            description: 'year of producction'
        ,
        
            type: 1,
            code: 2,
            value: 30,
            description: 'length'
        
    ]


se.save

轨道c

SELECT data->'params'->0 as data FROM smart_elements;

返回

                                 data
----------------------------------------------------------------------
 "type":1,"code":1,"value":2012,"description":"year of producction"
(1 row)

你可以继续嵌套

SELECT data->'params'->0->'type' as data FROM smart_elements;

返回

 data
------
 1
(1 row)

【讨论】:

以上是关于如何使用新的 PostgreSQL JSON 数据类型中的字段进行查询?的主要内容,如果未能解决你的问题,请参考以下文章

postgresql 函数 - 如何将新的 json 对象推送到 json 数组?

加载 back.json 文件 PostgreSQL 时出现重复键问题

将新的键/值对添加到 PostgreSQL JSON 列内的嵌套数组中

如何使用 laravel 更新 postgresql 数据库中的 json 数据?

如何修改新 PostgreSQL JSON 数据类型中的字段?

如何使用 java 从 PostgreSQL 数据库中的现有数据库创建新的 XML 文件 [关闭]