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

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

添加jsonb(b代表"二进制",值存储为本机Postgres类型)以及两种类型的更多功能。除了上面提到的表达式索引,jsonb还支持GIN,btree和哈希索引,GIN是最有效的。

  • 有关jsonjsonb数据类型和功能的手册。
  • 关于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

完整的jsonb函数和运算符。添加更多功能以在适当位置操作jsonb并进行显示。

  • Postgres 9.5的发行说明中的??主要好消息。


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

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

有关一些不错的示例和教程,请参阅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)