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


216

我正在寻找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文档存储的功能


3
就在最近,我找到了Matt Schinckel 撰写的
Knowbody 2014年

1
@knowbody这篇文章实际上是关于查询JSONB的,这与JSON截然不同。我不好意思没有在帖子中说清楚。
Matthew Schinckel

Answers:


177

Postgres 9.2

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

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

并不能阻止他提供应该解决您的问题的PLV8示例实现

Postgres 9.3

提供大量新功能和运算符,以添加“ json-processing”。

Postgres 9.3中原始问题的答案:

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

高级示例:

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

PostgreSQL 9.4

添加jsonb(b为“二进制”,值存储为本地Postgres类型),并且两种类型都具有更多功能。除了上面提到的表达式索引外,jsonb还支持GIN,btree和hash索引,其中GIN是最有效的。

该手册建议如下:

通常,大多数应用程序应该将JSON数据存储为 jsonb,除非有非常特殊的需求,例如关于对象键顺序的传统假设。

大胆强调我的。

性能从GIN索引的总体改进中受益。

Postgres 9.5

完整的jsonb功能和操作员。添加更多功能以jsonb就地操作和显示。


1
谢谢,我使用PLV8方法很快就遇到类型问题。看起来很有前途,但目前尚不可用。
Toby Hede

@TobyHede:猜猜我们将不得不等待9.3。
Erwin Brandstetter,2012年

1
@JoeShaw:谢谢,我进行了相应的更新,并添加了指向Postgres Wiki的链接。
Erwin Brandstetter

@ErwinBrandstetter如果我正在寻找WHERE elem->>'correct'='TRUE'; 并且JSON如下所示:“ correct”:“ TRUE”,查询逻辑项的正确方法是什么?
Shiraj

@Shiraj:请问新问题。评论不是地方。
Erwin Brandstetter

87

对于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/


2
在上面的示例中,您应该有一个以dataJSON文档命名的字段:{images:{thumbnail:{url:'thumbnail.jpg'}}}。让我们知道您的数据是什么样的,什么查询失败。
Meekohi 2014年


6
如何查询是否存在数组?我看到#>>运算符,但不知道如何使用它!
Mohamed El Mahallawy 2014年

在此选择查询中,我可以使用通配符吗?即SELECT data->'%'->'thumbnail'->'url' AS thumb FROM instagram;
巴拉特

@Meekohi的答案很好用:特别是我不需要::json其他帖子中所述。另请注意,->如果您尝试访问不存在的属性(即,如果您具有交错的JSON),则运算符将引发错误:ERROR: column "jsonPropertyYouWant" does not exist
Red Pea

19

对于postgres 9.3,请使用->进行对象访问。4例

seed.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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.