MaxComputeでJSONデータの扱い方

まだご存じの方が少ないかと思いますが、Alibaba Cloud <a href="https://jp.alibabacloud.com/help/product/72772.htm">DataWorks 2.0</a>には、JSONデータへのサポートが強化され、JSONドキュメントの処理及び分析が楽となります。IoTやWebアプリケーションなど、さまざまなデータソースから出力するログの形式がJSONで、<a href="https://jp.alibabacloud.com/help/doc-detail/48869.htm">Log Service</a>が収集したJSONデータをどのように加工するのかという質問が見えてくるので、今回の記事は、OSSへ事前にアップロードしたJSONドキュメントを例として、MaxComputeでJSONドキュメントの扱い方について、皆さんご紹介させて頂きたいと思います。

<!--more-->
<ul style="list-style-type: square;">
 	<li><strong><span style="font-size: 14pt;">事前準備</span></strong></li>
</ul>
まず、JSONファイル(text.txt)をOSSへアップロードします。本記事は、次のJSON ドキュメントを使用します。
<pre class="EnlighterJSRAW" data-enlighter-language="json">{
    "store": {
        "book": [
             {
                "category": "reference",
                "author": "Nigel Rees",
                "title": "Sayings of the Century",
                "price": 8.95
             },
             {
                "category": "fiction",
                "author": "Evelyn Waugh",
                "title": "Sword of Honour",
                "price": 12.99
             },
             {
                 "category": "fiction",
                 "author": "J. R. R. Tolkien",
                 "title": "The Lord of the Rings",
                 "isbn": "0-395-19395-8",
                 "price": 22.99
             }
          ],
          "bicycle": {
              "color": "red",
              "price": 19.95
          }
    },
    "expensive": 10
}</pre>

<ul style="list-style-type: square;">
<li><strong><span style="font-size: 14pt;">JSONドキュメントの同期</span></strong></li>
</ul>
まず、Data Integrationを通して、新たなデータソース(OSS)を追加します。本記事は、OSSのバケットとDataWorksプロジェクトが同じリージョンに設定しましたので、OSSのイントラネットエンドポイントを使いました。

<img class="alignnone size-full wp-image-5160" src="https://techblog.sbcloud.co.jp/assets/2019/02/スクリーンショット-2019-02-18-18.15.55.png" alt="" width="1274" height="476" />

次は、下記のMaxComputeSQL文で、JSONドキュメントを格納するテーブルを作成します。また、DataStudioでデータ同期のタスクを新規作成します。
<pre class="EnlighterJSRAW" data-enlighter-language="sql">DROP TABLE IF EXISTS json_tab;
CREATE TABLE json_tab (data_oss STRING);</pre>
続いて、データ同期タスクで、下記の手順でデータソース、ターゲットとフィールドマッピングを設定します。

<img class="alignnone size-full wp-image-5168" src="https://techblog.sbcloud.co.jp/assets/2019/02/スクリーンショット-2019-02-18-18.50.28.png" alt="" width="1732" height="440" />

最後、JSON ドキュメントが 1 行で構成されている必要がありますので、JSON ドキュメントの平坦化をする為に、上記の赤枠のタブをクリックして、スクリプトモードに変換します。スクリプトファイルのうち、"fileFormat"の項目に「text」との値を「binary」に書き換えます。そうすると、JSONデータがjson_tabテーブルの一行の文字列になります。
<pre class="EnlighterJSRAW" data-enlighter-language="json">{
    "type": "job",
    "steps": [
        {
            "stepType": "oss",
            "parameter": {
                "fieldDelimiterOrigin": "^",
                "nullFormat": "",
                "compress": "",
                "datasource": "oss",
                "column": [
                    {
                        "name": 0,
                        "index": 0,
                        "type": "string"
                    }
                ],
                "skipHeader": "false",
                "encoding": "UTF-8",
                "fieldDelimiter": "^",
                "fileFormat": "binary",
                "object": [
                    "test_1.txt"
                ]
            },
            "name": "Reader",
            "category": "reader"
        },
        {
            "stepType": "odps",
            "parameter": {
                "partition": "",
                "truncate": true,
                "datasource": "odps_first",
                "column": [
                    "data_oss"
                ],
                "emptyAsNull": false,
                "table": "json_tab"
            },
            "name": "Writer",
            "category": "writer"
        }
    ],
    "version": "2.0",
    "order": {
        "hops": [
            {
                "from": "Reader",
                "to": "Writer"
            }
        ]
    },
    "setting": {
        "errorLimit": {
            "record": ""
        },
        "speed": {
            "throttle": false,
            "concurrent": 2,
            "dmu": 1
        }
    }
}</pre>
下図のように、「select * from json_tab」の構文で、同期されたデータを簡単に確認することもできました。

<img class="alignnone size-full wp-image-5183" src="https://techblog.sbcloud.co.jp/assets/2019/02/スクリーンショット-2019-02-18-19.38.19-2.png" alt="" width="616" height="165" />

<ul style="list-style-type: square;">
<li><span style="font-size: 14pt;"><strong>JSONドキュメントの分析</strong></span></li>
</ul>
MaxCompute には、ランタイム処理中に JSON クエリを実行できる get_json_object という組み込み UDF があります。 このメソッドでは 2 つの引数 (テーブル名とメソッド名) を取り、解析が必要なフラット化された JSON ドキュメントと JSON フィールドが含まれます。 この UDF の動作を確認する例を見てみましょう。
<pre class="EnlighterJSRAW" data-enlighter-language="sql">SELECT
  GET_JSON_OBJECT(json_tab.data_oss,'$.store.bicycle.color'),
  GET_JSON_OBJECT(json_tab.data_oss,'$.store.bicycle.price')
FROM json_tab;</pre>
<img class="alignnone size-full wp-image-5181" src="https://techblog.sbcloud.co.jp/assets/2019/02/スクリーンショット-2019-02-18-19.36.52-1.png" alt="" width="686" height="156" />

<ul style="list-style-type: square;">
<li><span style="font-size: 14pt;"><strong>最後</strong></span></li>
</ul>
いかがでしたでしょうか、実業務中でJSONドキュメントを扱うケースがよくあると思いますので、皆さんのお役に立てば幸いです。