アプリケーションやITのシステムはプログラムの出来不出来でクオリティが決まると思っているのは非常に素人考えで、実は重要なのがデータ部分であることは、経験者なら誰もが同じことを口にするでしょう。
僕の経験では、世の中のITシステムトラブルの多くを占めているのはデータベース障害であるという事実も、エンジニアを仕事にしている人であれば、頷いてくれる内容です。
データベース障害を除きたければデータベースアプリケーションを使わなければいいんです!
という事で、jsonファイルをjqコマンドで直接使ってシステムを作り、オレオレデータベースを構築してSQL障害から開放された僕ですが、jqコマンドが非常に便利すぎて、Linuxで正規モジュールに採用してくれないかと切に願っております。
そんなjqコマンドを使っていて、あまり他の解説サイトやブログで書かれていない内容があったので、小さなトピックですが、備忘録として書いておきます。
ユニークIDが複数ある場合のunique_by命令の書き方
まずは、テストデータは以下のjsonデータを使います。
{"id1":1,"id2":"a","val":"aaa"}
{"id1":1,"id2":"b","val":"bbb"}
{"id1":1,"id2":"a","val":"ccc"}
{"id1":2,"id2":"b","val":"ddd"}
{"id1":2,"id2":"a","val":"eee"}
{"id1":2,"id2":"b","val":"fff"}
{"id1":3,"id2":"a","val":"ggg"}
{"id1":3,"id2":"b","val":"hhh"}
{"id1":3,"id2":"a","val":"iii"}
{"id1":4,"id2":"b","val":"jjj"}
これを"id1"のkey値でユニーク値を取得するには、
jq --slurp --compact-output 'unique_by(.id1) | .[]' sample.json
{"id1":1,"id2":"a","val":"aaa"}
{"id1":2,"id2":"b","val":"ddd"}
{"id1":3,"id2":"a","val":"ggg"}
{"id1":4,"id2":"b","val":"jjj"}
ユニークデータを後書き有効にする場合は、
jq --slurp --compact-output 'reverse | unique_by(.id1) | .[]' sample.json
先頭に"reverse"をつけるだけでいいんです。
{"id1":1,"id2":"a","val":"ccc"}
{"id1":2,"id2":"b","val":"fff"}
{"id1":3,"id2":"a","val":"iii"}
{"id1":4,"id2":"b","val":"jjj"}
さらにid2も含めたユニークにしたい場合は、
jq --slurp --compact-output 'reverse | unique_by(.id1,.id2) | .[]' sample.json
{"id1":1,"id2":"a","val":"ccc"}
{"id1":1,"id2":"b","val":"bbb"}
{"id1":2,"id2":"a","val":"eee"}
{"id1":2,"id2":"b","val":"fff"}
{"id1":3,"id2":"a","val":"iii"}
{"id1":3,"id2":"b","val":"hhh"}
{"id1":4,"id2":"b","val":"jjj"}
いかがでしょうか?複数keyでのユニーク化が簡単にできました。
しかも、後書き有効なので、追記型のログデータなどで活用することが可能になります。
押さえておきたいポイント
今回のポイントは、unique_by(path_exp)命令の中の"path_exp"の部分でコントロールするだけという事に気がついた人も多いと思います。
ここを極めれば、データ抽出はかなり柔軟にできるようになります。
今回の複数対象にしたい場合は、,(カンマ)区切りで書けばOKです。
ちなみに、順番もポイントで、以下のように入れ替えると結果も変わります。
jq --slurp --compact-output 'reverse | unique_by(.id2,.id1) | .[]' sample.json
{"id1":1,"id2":"a","val":"ccc"}
{"id1":2,"id2":"a","val":"eee"}
{"id1":3,"id2":"a","val":"iii"}
{"id1":1,"id2":"b","val":"bbb"}
{"id1":2,"id2":"b","val":"fff"}
{"id1":3,"id2":"b","val":"hhh"}
{"id1":4,"id2":"b","val":"jjj"}
書き込んだ順にソートされるようですが、抽出されるデータ自体は変わらないようですね。
この後でsort_byをしてもいいですが、unique_byの結果で一旦ソートがかかっているので、処理速度を早くしたければ、ここで一発で行うのがオススメです。
SQLだとSELECT文で同じことは出来るんですが、これらの相互コンバートできるプログラム作ったら便利そうだな・・・
0 件のコメント:
コメントを投稿