JSONをもっと便利に:json_accessors

本エントリは、PostgreSQL Advent Calendar 2012の12月22日分です。

昨日@choplinさんがpg-jsonpathのこと書いたばかりでアレですが、空気読まずにJSONネタ続けます :-P

json_accessorsって?

9.2からPostgreSQLに追加されたJSON型ですが、値にアクセスするための仕組みはあまり充実していません。そこで、json_accessorsというツールが開発され、PGXNで公開されています。なお、ソースはgithubで公開されています。

PGXNクライアントで一発インストールも可能ですが、今回はgithubから最新版を入れてみました。

[src]$ git clone git://github.com/theirix/json_accessors.git
Cloning into 'json_accessors'...
remote: Counting objects: 313, done.
remote: Compressing objects: 100% (120/120), done.
remote: Total 313 (delta 171), reused 299 (delta 157)
Receiving objects: 100% (313/313), 61.08 KiB, done.
Resolving deltas: 100% (171/171), done.
[src]$ cd json_accessors
[json_accessors]$ make; make install
...

json_accessorsはEXTENSION形式で作成されているので、psqlで接続してデータベースに登録します。

postgres=# CREATE EXTENSION json_accessors;
CREATE EXTENSION
postgres=# \dx
                           List of installed extensions
      Name      | Version |   Schema   |                Description                
----------------+---------+------------+-------------------------------------------
 json_accessors | 1.3.5   | public     | postgresql json accessor functions
 plpgsql        | 1.0     | pg_catalog | PL/pgSQL procedural language
(2 rows)

どうやら最新版は1.3.5のようです。地道にアップデートされてるようですね。含まれる関数群はpublicスキーマにインストールされるので、特に設定を変えなくてもすぐに利用できます。

json_accessorsでできること

json_accessorsで提供されている機能は、以下の三つに分類できます。

  • JSON配列からPostgreSQL配列に変換
  • JSON値から属性名指定でスカラー値(int/text/etc.)を取得
  • JSON値から属性名指定で配列値(int/text/etc.)を取得

JSON値から値を取得する機能では、JSONオブジェクトの文字列表現(text型)も取得できるようです。以下の例では、JSON値を使った検索条件で絞り込みをしています。

postgres=# select * from users order by id;
-[ RECORD 1 ]----------------------------------------------------------
id         | 1
name       | Saito
attributes | {"carrior":"softbank", "model":"iPhone-5","maker":"Apple"}
-[ RECORD 2 ]----------------------------------------------------------
id         | 2
name       | Takahashi
attributes | {"carrior":"au", "model":"A01","maker":"iida"}
postgres=# SELECT name FROM users WHERE
postgres-# json_get_text(attributes::text, 'maker') = 'Apple';
 name  
-------
 Saito
(1 row)

JSON値を受け取る引数がtext型で定義されているので毎回キャストしないといけないのがイマイチな感じもありますが、素のPostgreSQLに比べるとかなり簡単にJSONにアクセスできるようになったのではないでしょうか。

まとめ

今回はツールの簡単な紹介で終わってしまいましたが、外部ツール特有のフットワークの軽さで色々発展していくと思われます。githubで公開されていますので、pull requestを送ってみるのも一興かと。