How do I query using fields inside the new PostgreSQL JSON datatype?
我正在为PostgreSQL 9.2中的新JSON函数寻找一些文档和/或示例。
具体来说,给定一系列JSON记录:
1 2 3 4 | [ {name:"Toby", occupation:"Software Engineer"}, {name:"Zaphod", occupation:"Galactic President"} ] |
如何编写SQL以按名称查找记录?
在vanilla SQL中:
1 | 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
更新我
我已经汇总了详细介绍PostgreSQL 9.2目前可能实现的内容。
使用一些自定义函数,可以执行以下操作:
1 2 | SELECT id, json_string(DATA,'name') FROM things WHERE json_string(DATA,'name') LIKE 'G%'; |
更新II
我现在已将我的JSON函数移动到他们自己的项目中:
PostSQL - 一组用于将PostgreSQL和PL / v8转换为完全令人敬畏的JSON文档存储的函数
Postgres 9.2
我在pgsql-hackers列表中引用Andrew Dunstan:
At some stage there will possibly be some json-processing (as opposed
to json-producing) functions, but not in 9.2.
不妨碍他在PLV8中提供应该解决您的问题的示例实现。
Postgres 9.3
提供一系列新功能和操作员来添加"json-processing"。
- 有关新JSON功能的手册。
- 关于第9.3页的新功能的Postgres Wiki。
- @Will会在下面的评论中发布一个博客链接,展示新运营商。
Postgres 9.3中原始问题的答案:
1 2 3 4 5 6 | SELECT * FROM json_array_elements( '[{"name":"Toby","occupation":"Software Engineer"}, {"name":"Zaphod","occupation":"Galactic President"} ]' ) AS elem WHERE elem->>'name' = 'Toby'; |
高级示例:
- 使用JSON数据类型的嵌套记录数组查询组合
对于较大的表,您可能需要添加表达式索引以提高性能:
- 用于在JSON数组中查找元素的索引
Postgres 9.4
添加
-
有关
json 和jsonb 数据类型和功能的手册。 - 关于JSONB的Postgres Wiki,见第9.4页
该手册甚至建议:
In general, most applications should prefer to store JSON data as
jsonb , unless there are quite specialized needs, such as legacy
assumptions about ordering of object keys.
大胆强调我的。
性能受益于GIN索引的一般改进。
Postgres 9.5
完整的
- Postgres 9.5的发行说明中的??主要好消息。
使用Postgres 9.3+,只需使用
有关一些不错的示例和教程,请参阅http://clarkdave.net/2013/06/what-c??an-you-do-with-postgresql-and-json/。
使用postgres 9.3使用 - >进行对象访问。 4个例子
seed.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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 |
铁轨
1 | SELECT data->'params'->0 AS DATA FROM smart_elements; |
回报
1 2 3 4 | DATA ---------------------------------------------------------------------- {"type":1,"code":1,"value":2012,"description":"year of producction"} (1 ROW) |
您可以继续嵌套
1 | SELECT data->'params'->0->'type' AS DATA FROM smart_elements; |
返回
1 2 3 4 | DATA ------ 1 (1 ROW) |