新しい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"

公式の開発マニュアルはかなりまばらです:

アップデートI

PostgreSQL 9.2で現在可能なことを詳しく説明した要点をまとめました。一部のカスタム関数を使用すると、次のようなことが可能になります。

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

アップデートII

JSON関数を独自のプロジェクトに移動しました。

PostSQL -PostgreSQLとPL / v8を完全に素晴らしいJSONドキュメントストアに変換するための一連の関数


3
つい最近、Matt Schinckelによるこのブログ投稿を見つけました。PostgreSQLでのJSONのクエリについて詳細に説明していますschinckel.net/2014/05/25/querying-json-in-postgres
Knowbody

1
@knowbodyこの投稿は、実際にはJSONBのクエリに関するもので、JSONとはまったく異なります。投稿でそれを明確にしていないのは残念です。
Matthew Schinckel、2016

回答:


177

Postgres 9.2

はpgsql-hackersリストでAndrew Dunstanを引用しています:

ある段階では、json-processing機能(json-producingとは対照的)が存在する可能性がありますが、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';

高度な例:

大きなテーブルの場合、式インデックスを追加してパフォーマンスを向上させることができます。

Postgres 9.4

追加jsonb(「バイナリ」の場合はb、値はネイティブのPostgres型として格納されます)、さらに両方の型の機能性。上記の式インデックスに加えて、GIN、btree、ハッシュインデックスjsonbもサポートしています。GINはこれらの中で最も強力です。

マニュアルは示唆するところまで行きます:

一般に、ほとんどのアプリケーションではjsonb、オブジェクトキーの順序に関する従来の前提など、特別なニーズがない限り、JSONデータをとして保存することをお勧めし ます。

大胆な強調鉱山。

GINインデックスの全般的な改善により、パフォーマンスが向上します。

Postgres 9.5

完全なjsonb関数と演算子。そのjsonb場で操作して表示するための関数をさらに追加します。


1
おかげで、PLV8のアプローチを使用すると、型の問題に非常に早く遭遇しました。有望に見えますが、現時点では実際には使用できません。
Toby Hede

@TobyHede:9.3を待つ必要があると思います。
Erwin Brandstetter、2012年

1
@JoeShaw:ありがとう、それに応じて更新し、Postgres Wikiへのリンクを追加しました。
Erwin Brandstetter、2013

@ErwinBrandstetter WHERE elem->> 'correct' = 'TRUE';を探している場合 そしてJSONは次のようになります:「正しい」:「TRUE」、論理用語をクエリする正しい方法は何ですか?
シラジ2017年

@Shiraj:として、新たな質問をしてください質問。コメントは場所ではありません。
Erwin Brandstetter 2017年

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
上記の例dataでは、JSONドキュメントで名前が付けられたフィールドが必要です{images:{thumbnail:{url:'thumbnail.jpg'}}}。データがどのように表示され、どのクエリが失敗したかをお知らせください。
Meekohi 2014年


6
配列がある場合、どのようにクエリできますか?#>>演算子は表示されますが、使用方法の手がかりはありません。
Mohamed El Mahallawy 2014

この選択クエリではワイルドカードを使用できますか?IeSELECT data->'%'->'thumbnail'->'url' AS thumb FROM instagram;
バーラト2018

@Meekohiの答えはうまくいきます:特に::json他の投稿で説明されているように私は必要としませんでした。また、注意してください->、あなたが存在しないプロパティにアクセスしようとすると、エラーがスローされます演算子(つまり、あなたはJSONをずらしている場合):ERROR: column "jsonPropertyYouWant" does not exist
赤エンドウ

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)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.