3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

JSONs(仮) のすすめ

Posted at

はじめに

みんな大好き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(仮)と呼びます。

(このフォーマットの空白に関する記述がないものは、英語版のwikiConcatenated JSONとして載っています。)

JSONs(仮)には似たようなフォーマットがいくつかありますので、2つほど紹介します。

JSON Text Sequences

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からのデータを使って下のようなサービスを作っているのですが、その時にそのデータをどうやって保存するかという問題に直面したからです。

スクリーンショット 2022-09-27 0.38.17.png

JRA-VANからは毎日のようにデータを送ってきます。例えばレース情報ならレース単位にレコードが送られています。これまでは1レコードをJSON化してローカルのMongoDBに蓄えて、必要な時にJSONに戻していました。
ただ、このサービスはfirebaseで作りたかったので、firestoreに載せ替えようとやってみたところ全データ載せると結構な費用が発生することがわかって断念しました。

で思いついたのが、初めからJSONs(仮)の形にしてローカルのファイルに保存して、必要な情報だけ抜き出してJSONにしてfunctionshostingにデプロイするというやり方です。これだったらfirestoreさえ必要ないです。ローカルのファイルをJSONにしてもよかったのですが、何故JSONs(仮)にしたかというと大きく2つあります。

  • JSONs(仮)であればダウンロードされたレコードをJSON化して単にファイルの後ろに書いてやればいい。

  • 結構なデータ量のデータ、例えばレース毎馬情報みたいなのがあるんですが、JSONで一気に読むと時間とメモリがちょっと大変な感じになる懸念がある。

JSONs(仮)の懸念と対策

JSONs(仮)をデータベースの代わりに使いたくなってくるのですが、以下のような懸念点があります。

  • 検索の開発コストが必要

SQLなどが使えないのでクエリーは自前でプログラミングしなくてはなりません。ただし、その分自由度が高いです。

  • メモリと処理時間

データベースの代わりに使うような場合、メモリに入ればいいのですが、入らなければ読みながら処理をする必要がありますのでちょっと処理時間が問題になりそうです。あらかじめ前処理するとか、自前でインデックスを用意しておくとかが自在ですが開発コストがかかりそうです。

  • ローカルに置けない

セキュリティ等の関係で、データは全部クラウド、みたいな場合がありそうです。例えばGCPではストレージにアペンドできないのでインスタンスを用意しておいてそこにおいてやる、みたいなことをする必要があるかもしれません。

  • ロックとかバッチとかトリガーとかがない。

一応やれなくはないとは思うのですが、開発コストがかかりそうです。

最後に

手前味噌で申し訳ないのですが、もしJRA-VANのデータをMongoDBに蓄えたい場合は、よかったら拙作JV2Mongoを使ってやってください。

最後までお読みいただきありがとうございました。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?