はじめに
みんな大好きjq
の入力って、実は単なるJSON
じゃないの知ってます?
% man jq
jq can transform JSON in various ways, by selecting, iterating, reducing and otherwise mangling JSON documents. For instance, running the command jq ´map(.price) | add´ will take an array of JSON objects as input and return the sum of their "price" fields.
jq can accept text input as well, but by default, jq reads a stream of JSON entities (including numbers and other literals) from stdin. Whitespace is only needed to separate entities such as 1 and 2, and true and false. One or more files may be specified, in which case jq will read input from those instead.
つまりJSON
の連続です。数や真偽値同士が続く時にはその間にWhitespace
つまり空白とか改行とかが必要になります。あと書いてないんですが、null
も同様にWhitespace
が必要です。
% echo '{"price":100}{"price":200}' | jq .price
100
200
% echo '1 null true' | jq .
1
null
true
このフォーマットには名前が付いてないようなので、ここでは仮にJSONs
(仮)と呼びます。
(このフォーマットの空白に関する記述がないものは、英語版のwiki
でConcatenated JSONとして載っています。)
JSONs(仮)
には似たようなフォーマットがいくつかありますので、2つほど紹介します。
JSON Text Sequences
複数のJSON
をそれぞれ,
と\n
で囲む形式です。延々JSON
をストリーミングする時に、途中から読んでもJSON
の始まりがわかるというのが目的のフォーマットです。
1行1JSONと言われるやつ
各々のJSON
を必ず1行で記述して、後ろに\n
をつけるフォーマットです。ストリーミングにも使えるというメリットがありますが、各々のJSON
を1行で記述しなくてはいけないため、人に読ませる用途には向きません。JSON Lines
とかLDJSON
とも呼ばれます。規格化されているわけではないので他の名前もたくさんありそうです。
JSONs(仮)の特徴
- ほとんどの場合、単に複数の
JSON
を繋げばいいので手軽です。 - 各々の
JSON
が1行で書けるとわかっている場合はつなぐ時間に\n
を挟んでやれば「1行1JSONと言われるやつ」になります。 - 途中から読むとどこが次の
JSON
の始まりかわからないので、ストリーミングには使えません。
JSONs(仮)の実際
何でこんな記事を書いているかというと、趣味でJRA-VAN
からのデータを使って下のようなサービスを作っているのですが、その時にそのデータをどうやって保存するかという問題に直面したからです。
JRA-VAN
からは毎日のようにデータを送ってきます。例えばレース情報ならレース単位にレコードが送られています。これまでは1レコードをJSON
化してローカルのMongoDB
に蓄えて、必要な時にJSON
に戻していました。
ただ、このサービスはfirebase
で作りたかったので、firestore
に載せ替えようとやってみたところ全データ載せると結構な費用が発生することがわかって断念しました。
で思いついたのが、初めからJSONs(仮)の形にしてローカルのファイルに保存して、必要な情報だけ抜き出してJSON
にしてfunctions
やhosting
にデプロイするというやり方です。これだったらfirestore
さえ必要ないです。ローカルのファイルをJSON
にしてもよかったのですが、何故JSONs(仮)にしたかというと大きく2つあります。
-
JSONs(仮)であればダウンロードされたレコードを
JSON
化して単にファイルの後ろに書いてやればいい。 -
結構なデータ量のデータ、例えばレース毎馬情報みたいなのがあるんですが、
JSON
で一気に読むと時間とメモリがちょっと大変な感じになる懸念がある。
JSONs(仮)の懸念と対策
JSONs(仮)をデータベースの代わりに使いたくなってくるのですが、以下のような懸念点があります。
- 検索の開発コストが必要
SQL
などが使えないのでクエリーは自前でプログラミングしなくてはなりません。ただし、その分自由度が高いです。
- メモリと処理時間
データベースの代わりに使うような場合、メモリに入ればいいのですが、入らなければ読みながら処理をする必要がありますのでちょっと処理時間が問題になりそうです。あらかじめ前処理するとか、自前でインデックスを用意しておくとかが自在ですが開発コストがかかりそうです。
- ローカルに置けない
セキュリティ等の関係で、データは全部クラウド、みたいな場合がありそうです。例えばGCP
ではストレージにアペンドできないのでインスタンスを用意しておいてそこにおいてやる、みたいなことをする必要があるかもしれません。
- ロックとかバッチとかトリガーとかがない。
一応やれなくはないとは思うのですが、開発コストがかかりそうです。
最後に
手前味噌で申し訳ないのですが、もしJRA-VAN
のデータをMongoDB
に蓄えたい場合は、よかったら拙作JV2Mongo
を使ってやってください。
最後までお読みいただきありがとうございました。