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

问题描述 投票:0回答:3

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

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

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

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

在普通 SQL 中:

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

官方开发手册相当稀疏:

更新我

我整理了一个要点,详细说明了 PostgreSQL 9.2 目前可以实现的功能。 使用一些自定义函数,可以执行以下操作:

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

更新二

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

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

sql json postgresql postgresql-9.2 postgresql-9.3
3个回答
210
投票

Postgres 9.2

我在 pgsql-hackers 列表中引用 Andrew Dunstan

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

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

Postgres 9.3

提供一系列新函数和运算符来添加“json-processing”。

Postgres 9.3 中原始问题的答案:

对于给定的表:

CREATE TABLE json_tbl (data json);

查询:

SELECT object
FROM   json_tbl
     , json_array_elements(data) AS object
WHERE  object->>'name' = 'Toby';

高级示例:

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

Postgres 9.4

添加

jsonb
(b 表示“二进制”,值存储为本机 Postgres 类型)以及 both 类型的更多功能。除了上面提到的表达式索引之外,
jsonb
还支持GIN、btree和哈希索引,其中GIN是最有效的。

手册尽可能建议:

一般来说,大多数应用程序应该更喜欢将 JSON 数据存储为

jsonb
,除非有相当特殊的需求,例如遗留 关于对象键排序的假设。

我的粗体强调。
此外,性能还受益于 GIN 索引的总体改进。

Postgres 9.5

完整的

jsonb
函数和运算符。添加更多功能来操纵
jsonb
并进行显示。

此后每个主要 Postgres 版本的功能和性能都得到了改进。现在已经相当完整了(从 Postgres 16 开始)。一项重要的、值得注意的补充...

Postgres 12

... 是 SQL/JSON 路径语言以及运算符和函数。对于给定的表(带有

jsonb
),问题中示例的答案现在可以是:

CREATE TABLE jsonb_tbl (data jsonb);

SELECT jsonb_path_query_first(data, '$[*] ? (@.name == "Toby")') AS object
FROM   jsonb_tbl
WHERE  data @> '[{"name": "Toby"}]';  -- optional, for index support

或同等的:

...
WHERE  data @@ '$[*].name == "Toby"';

小提琴

参见:

关于索引:


123
投票

对于 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/ 获取一些不错的示例和教程。


26
投票

在 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)
© www.soinside.com 2019 - 2024. All rights reserved.