我正在寻找 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 文档存储的函数
我在 pgsql-hackers 列表中引用 Andrew Dunstan :
在某个阶段可能会有一些 json 处理(与 到 json 生成)函数,但 9.2 中没有。
并不妨碍他提供 PLV8 中的示例实现来解决您的问题。 (链接现已失效,请参阅现代的PLV8。)
提供一系列新函数和运算符来添加“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';
高级示例:
对于更大的表,您可能需要添加表达式索引以提高性能:
添加
jsonb
(b 表示“二进制”,值存储为本机 Postgres 类型)以及 both 类型的更多功能。除了上面提到的表达式索引之外,jsonb
还支持GIN、btree和哈希索引,其中GIN是最有效的。
手册尽可能建议:
一般来说,大多数应用程序应该更喜欢将 JSON 数据存储为
,除非有相当特殊的需求,例如遗留 关于对象键排序的假设。jsonb
我的粗体强调。
此外,性能还受益于 GIN 索引的总体改进。
完整的
jsonb
函数和运算符。添加更多功能来操纵 jsonb
并进行显示。
此后每个主要 Postgres 版本的功能和性能都得到了改进。现在已经相当完整了(从 Postgres 16 开始)。一项重要的、值得注意的补充...
... 是 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"';
参见:
关于索引:
对于 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/ 获取一些不错的示例和教程。
在 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)