Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

BigQuery JSON APIレスポンスを再帰的に変換する

By Eben Du ToitMar 25, 20192 min read

このページはEnglishDeutschEspañolFrançaisItalianoPortuguêsでもご覧いただけます。

1 vnu9dfxo8kvsal2frcxeeg

field/value形式でネストされた行から、キーと値のペアを組み立てる

1 vnu9dfxo8kvsal2frcxeegバルセロナのサグラダ・ファミリア(撮影:Paolo Nicolello)

声に出して言ってみてください。「ネストされたJSONは扱いにくい!」。そう思いませんか?間違いなく、その通りです。それはさておき、私はJSONそのものを心から信頼しています。論理的で、普遍的で、多くの言語が高速アクセス可能なハッシュマップ型のデータ構造を表現するためにJSONを採用しています。まさに万人にとっての勝利です。

――ネストするまでは、ですが。

ここで登場するのが、ネストされたJSONの利点を信奉する人々と、フラット化されたJSONこそがAPIペイロードの理想だと信じる人々です。この静かなる論争はあまりにも激しく、世のリポジトリにはフラット化のテクニックが無数に存在します。たとえば再帰的な手法非再帰的な手法などがその一例です。


再帰で「巣立ち」させる

映画『インセプション』をご覧になったことはありますか?名作です。タイムラインの中にタイムライン、さらにその中にタイムラインが入れ子になっていて、すべてが巻き戻ったときに各層がどうつながっていたかが見えてくる。再帰もこれと同じで、コード上の記述量はごくわずかでも、膨大な計算上の(つまり「ネストされた」)複雑さに対応できるのです。

前置きはこのくらいにして、本題に入りましょう。

BigQueryのクエリAPIが返すJSON

以下は、Google BigQueryでクエリを実行した際のAPIレスポンスのサンプルです。

https://gist.github.com/ebendutoit/b160b66f3ba4073686d277524d210b90

スキーマがデータ構造を示し、行が**「f」=field(フィールド)「v」=value(値)**として、どの値がどのスキーマに対応するかを表しています。

では、JSONが次のような形になっていたほうが、読みやすく扱いやすいと思いませんか?

https://gist.github.com/ebendutoit/07832a24d9cedf436cb394b7bc6ea136

そう思った方は、もう安心です。

解決策

こちらが、その変換を行う**node.js**のコードです。自由にお使いいただき、用途に合わせて手を加え、作業を楽に、データを扱いやすくしてください。関数のインターフェースは次のとおりです。

convertBQToMySQLResults(schema, rows)

BigQueryのレスポンスは、次のように渡します。

// apiResponse is the payload you receive from a BigQuery query API // response
convertBQToMySQLResults(apiResponse.schema.fields, apiResponse.rows)

https://gist.github.com/ebendutoit/1717e5eba2f55ab23544153d2ef098a8


JsFiddleのデモ

実際に試せるコードのJsFiddleデモはこちらです。

[wp-js-fiddle url="https://jsfiddle.net/ebendutoit/4rvgnob2/" style="width:100%; height:400px; border:solid #4173A0 1px;"]

まとめ

JSONの変換手法は世の中に数多く存在します。再帰的な実装はデバッグしやすいとは言えませんが、コード量は最小限で済みます。こうしたアルゴリズムを「スローモーション」で確認するには、デバッガでステップ実行するのが一番です。本記事では、Google BigQueryから返される複雑にネストされたJSONをフラット化し、自分の使いやすい形に整える一つの方法をご紹介しました。ぜひお試しください。快適な変換ライフを!