PostgreSQL で JSON 型データを条件に検索するには?

人の世を作ったものは神でもなければ鬼でもない。やはり向う三軒両隣にちらちらするただの人である。

夏目漱石「草枕」より

こんにちは、勤め人なのに昼夜逆転と寝不足で自立神経が整わない hikaru-kimi です!

弊社のような自社サービスを運営している企業ですと、不具合調査や動作検証のためにデータベースを操作することもままあります

O/Rマッパー(Rails で言えば ActiveRecord)で手軽にデータを確認することもありますが、環境によってはSQLを用いて直接データベースを調査する場面もあります

テーブルのカラムによっては JSON 型を採用しているものもありますが、JSON の中身を条件に where 句で指定したい場合もあるのではないでしょうか

今回は、PostgreSQL で JSON を取り扱う方法についてまとめてみました

出典: https://www.postgresql.jp/docs/9.4/functions-json.html

以下のようなテーブルとデータを前提に解説します

postgres=# \d books;
              Table "public.books"
 Column  | Type | Collation | Nullable | Default 
---------+------+-----------+----------+---------
 details | json |           | not null | 

postgres=# select * from books;
              details              
-----------------------------------
 {"a": 1, "b": "def", "c": "hoge"}
 {"a": 2, "b": "end", "c": "fuga"}
(2 rows)

books.details の "b" キーが 'def' であるレコードを抽出したい場合、->> でアクセスします

postgres=# select * from books where details->>'b' = 'def';
              details              
-----------------------------------
 {"a": 1, "b": "def", "c": "hoge"}
(1 row)

また、特定のデータを含んでいるレコードの検索であれば、JSON を文字列にして特定の文字列を含んでいるかどうかで抽出するのも一考の価値があるのではないでしょうか

postgres=# select * from books where details::text like '%def%';
              details              
-----------------------------------
 {"a": 1, "b": "def", "c": "hoge"}
(1 row)

これはやや大雑把な面も否めませんが、JSON を扱う際の特有の演算子を正確に使用するよりは簡単に取り扱えますね

歴史という名の大河

如月の寒空に吹き荒ぶ冬風に凍えた部屋で、現在私はこの記事を認めています

この冬風は、人の住まわぬ不毛の地シベリアで発生した極寒の冷気が、広大な中国大陸の上空を通過し、荒波の日本海を越え、そして今私の住むこの水都大阪に吹き付けているのです

この技術もまた、現在の形を取るまでに多くの名もなき技術者たちが苦悶し、議論を重ね、そして決断を繰り返してきたという歴史を織り成してきたわけですが、私はその奥深さに思いを馳せずにはいられません

そして、まるで長江をも思わせる大河のような歴史を鑑みると、私は悠久という言葉さえも空虚に感じ、言葉では到底表しきれないような深い感慨に囚われてしまいます

人類の歴史は、得てして、時の指導者を標石として語られることが多いです。しかし、歴史とは畢竟、名もなき無辜の人々の果てない努力と人知れない蹉跌とが連綿と折り重なって構成されているのではないでしょうか

そんな人類の歩みへと思いを巡らせていたら、宵も深まってきました。睡眠不足の体を労わるためにPCを閉じてベッドへ向かわんとすると、ふとカーテンの隙間から冬の夜空が垣間見えるではありませんか。吸い寄せられるかのようにベランダへ出て大阪の夜空を見上げると、澄んだ空気の向こうには正円を模った満月が浮かんでいます。 そんな夜空を仰ぎながら、私が生まれ育ち、学生時代を過ごした、大阪から見ると遥か遥か東に位置する街で学んだ李白の五言絶句が、なぜだか頭に浮かんでは離れません。疑うらくは是、地上の霜かと。

弊社サービス Re:lation の開発の歴史に名を刻みたいという方は、是非以下のリンクより採用サイトへのご応募をお願いいたします