スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

PostgreSQLでJSONの中身を取得する

PostgreSQL9.2からJSON型がサポートされましたが、列からJSON型と配列からJSON型に変換する関数しかありません。つまりJSON型で保存するとその形のままでしか取得できません。
JSONの一部の値で絞り込みをしたり、SELECT句で一部の値を取得できないんです。
これでは使い物になりません。
ですが、plv8を使うとそれが可能になります。
-- JSONの中身を取得する
-- p_src : JSONの値
-- p_key : キー
-- p_def : デフォルト値。型を特定する
CREATE OR REPLACE FUNCTION uv8_get_value(
p_src JSON
,p_key TEXT
,p_def ANYELEMENT DEFAULT NULL::TEXT
) RETURNS ANYELEMENT AS $FUNCTION$
if (null === p_src) {
return p_def;
}
var result = p_src[p_key];
if (undefined === result) {
return p_def;
} else {
return result;
}
$FUNCTION$ LANGUAGE plv8;

使い方は以下の通りです。
select uv8_get_value('{"a":"b","b":1,"c":true,"d":[1,2],"e":null}', 'a')
→ b
select uv8_get_value('{"a":"b","b":1,"c":true,"d":[1,2],"e":null}', 'b')
→ 1
select uv8_get_value('{"a":"b","b":1,"c":true,"d":[1,2],"e":null}', 'c')
→ true
select uv8_get_value('{"a":"b","b":1,"c":true,"d":[1,2],"e":null}', 'c', NULL::BOOLEAN)
→ t
select uv8_get_value('{"a":"b","b":1,"c":true,"d":[1,2],"e":null}', 'd')
→ 1,2
select uv8_get_value('{"a":"b","b":1,"c":true,"d":[1,2],"e":null}', 'd', NULL::TEXT[])
→ {1,2}
select uv8_get_value('{"a":"b","b":1,"c":true,"d":[1,2],"e":null}', 'e')
→ null
select uv8_get_value('{"a":{"f":"g"}}', 'a')
→ [object Object]
select uv8_get_value('{"a":{"f":"g"}}', 'a', NULL::JSON)
→ {"f":"g"}
select uv8_get_value(uv8_get_value('{"a":{"f":"g"}}', 'a', NULL::JSON), 'f')
→ g

この関数の肝は、3番目のデフォルト値の型と戻りの型です。
3番目の型によって戻り値の型が確定されます。デフォルトではTEXTにしています。
これがないと配列型の値が正しくPostgreSQLで扱えません。
配列型以外は暗黙のキャストでどうにかなりますが、配列型だけは明示的にNULL::TEXT[]のようなデフォルト値を与えましょう。
スポンサーサイト
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。