JSONをTreasureDataにスムーズにいれたい

TreasureDataを利用していて一番むずかしいのがJSONファイルの扱いである。

以下のタイプのようなJSONファイルを入れることは簡単だ。
そのままDataConnectorのJSON parserを使ってくれればいい。

 { "name": "Tanaka", "age": 26 }
{ "name": "Suzuki", "age": 58 }

実際にデータが投入されると次のようになる。

time record
1586071993 { "name": "Tanaka", "age": 26 }
1586071993 { "name": "Tanaka", "age": 26 }

だけど次のようなJSONだと途端に難しくなる。

[

    {
        "name":"Tanaka",
        "age":26
    },
    {
        "name":"Suzuki",
        "age":58
    }

]

これをTreasureDataに入れると1カラムに全てのJSONファイルが入ってしまう。

time record
1586071993 [ { "name": "Tanaka", "age": 26 },{ "name": "Suzuki", "age": 58 }]

正直取り回しが悪い。 こういったときはpytdというTreasureDataのpythonライブラリを使うと良い。

import pytd.pandas_td as td
import pandas as pd
con = td.connect(apikey=<Your API key>)
df = pd.read_json('path/to/json=file')
td.to_td(df, 'your_databaes.your_table', con, if_exists='replace')

PandasでJSONを読み込み、それをCSVに変換してUploadしている。
この方法を使うとこんな感じでデータがUploadされる。

time name age
1586071993 Tanaka 26
1586071993 Suzuki 58

個人的にはこっちのほうがスッキリしていて好きである。 TreasureDataへのJSONの投入に悩んでいる人はこれを試してほしい。

Hive/PrestoでのJSONの展開方法

Hiveでのjsonの展開方法についてのメモ

こんなJSONを無邪気に入れてしまっていないだろうか。

[{"key":"k1","value":"v11"},{"key":"k2","value":"v12"}]

さてこのデータをこんな感じのテーブルに展開したいが、どうしたらいいのだろうか。 配列で入ってればそのままExplodeすればいいが、Stringで格納されている場合はどうしたらいいのだろうか。

key value
k1 v11
k2 v12

答えだけを知りたい人は以下を参照されたし。

WITH source AS (
SELECT 'KEY001' AS key_col, '[{"key":"k1","value":"v11"},{"key":"k2","value":"v12"}]' AS json_array_col
UNION ALL
SELECT 'KEY002' AS key_col, '[{"key":"k2","value":"v22"},{"key":"k3","value":"v23"}]' AS json_array_col
UNION ALL
SELECT 'KEY003' AS key_col, '[{"key":"k1","value":"v31"},{"key":"k3","value":"v33"}]' AS json_array_col
)

SELECT 
       get_json_object(single_json_table.single_json, '$.key') AS key,
       get_json_object(single_json_table.single_json, '$.value') AS value
FROM
(SELECT EXPLODE(split(regexp_replace(substr(json_array_col,2,LENGTH(json_array_col)-2),'\\},', '},,,,'),',,,,')) as single_json from source) single_json_table

何をやっているか

目的 : 複数のjson一行に格納されているため、1行あたり1JSONにする。 => EXPLODEを使う。

大体の場合こういったJSONはデータを格納することを第一目的にしているため、Stringになっている。 残念ながら、そのままExplodeは使えない。 ではどうするか? 配列を返す関数をSplitを挟むのだ。

案1 : そのままSplitをする。

これを採用するとjsonでもarrayでもなにかが生成される。

SELECT EXPLODE(split(json_array_col,'\},')) as single_json from source
col1
[{"key":"k1","value":"v11"
{"key":"k2","value":"v12"}]

案2 [ ]を外して文字列にする。

1. 配列の [ ] を外す

SELECT substr(json_array_col,2,LENGTH(json_array_col)-2) as single_json from source

こんな感じの結果が返ってくる。

col1
{"key":"k1","value":"v11"},{"key":"k2","value":"v12"}

2. 分割(Split)したい箇所をSplitしやすいように,を,,にする。

SELECT regexp_replace(substr(json_array_col,2,LENGTH(json_array_col)-2),'\},', '},,') as single_json from source

なぜこんなことをするか。最終的にEXPLODEしたものはJSONとして取り回したいのだ。 もし、この過程を無視してしまうと以下のようなデータが生成されてしまう。

col1
["{\"key\":\"k1\",\"value\":\"v11\"","{\"key\":\"k2\",\"value\":\"v12\"}"]

Splitの結果として当然ながら'},'は消失する。 結果としてJSONとして扱えないデータにしかならないのだ。

そのためregexp_replaceを使って、別のメルクマークを作成するのだ。

3. Splitして配列にする。

SELECT split(regexp_replace(substr(json_array_col,2,LENGTH(json_array_col)-2),'\},', '},,'),',,') as single_json from source

こんな感じの結果になる。

col1
["{\"key\":\"k1\",\"value\":\"v11\"}","{\"key\":\"k2\",\"value\":\"v12\"}"]

ようやくほしい形の配列になった。

4. Explodeする。

SELECT EXPLODE(split(regexp_replace(substr(json_array_col,2,LENGTH(json_array_col)-2),'\},', '},,'),',,')) as single_json from source

結果はこうだ。

col1
{"key":"k1","value":"v11"}
{"key":"k2","value":"v12"}

あとは好きにJSONとして加工してくれればいい。

Treasure DataにおけるBulk Importの種類について

TreasureDataにデータを入れる方法について

大まかに以下の2種類が存在する。

  1. Streaming Import
  2. Bulk import

Streaming Importってなに

fluentdやjs-sdkなどを利用して、リアルタイムで生成されているデータを転送する方法。 1回あたりにインポートされるレコード数も少ない

Bulk Importってなに

DBのテーブルなどの大きなデータをまとめて、転送する方法。

今回の記事では2のBulk Importについて話をする。

Treasure Dataで利用できるBulk Importの種類について

大まかに以下の3つの方法が存在する。

  1. DataConnector
  2. Bulk import(Embulk)
  3. Legacy Bulk Import

それぞれの違いは以下の通り。

比較項目 Data Connector Bulk Import Legacy Bulk Import
概要 Treasure DataがホストするEmbulkサービス Embulk with embulk-output-td td import:xxx コマンド
リソース Data Connector専用のリソースを利用 Hiveのリソース(Hadoopのリソースを利用する) Hiveのリソースを利用する(詳細についてはこのドキュメントを参照推奨Legacy Bulk Import Internals – Arm Treasure Data)
メンテナンス性 Treasure Dataが開発・メンテナンスする オープンソース 開発は停止

使い分けについて

  • S3などの外部からアクセス可能なサービスにCSVファイルやTSVファイルの形式でファイルを置いている場合

この場合は特に自分でリソースを用意する必要がないため、Data Connectorを使った方がいい。

  • OracleなどのDBを利用し、外部サービスにデータをDumpできない場合

この場合はBulk Import(Embulk)を利用した方がいい。 Data Connectorからのアクセスを許可するために外との口を持つ必要があるからだ。

legacy bulk importについて

既に開発停止されているため、基本的には使用しないほうがいい。

サポートへの質問の仕方について思うこと

サポートってなんだ

サポートの仕事を始めておおよそ半年。

その中で感じたことを思うままに綴るポエムです。

サポートって何だ?

サポートは顧客の技術的な課題を解決するロールである。

ソリューションアーキテクト(以下、SA)やプロフェッショナルサービス(以下、PS)との違いは、技術的な課題の範囲である。

顧客は別に自社のサービスのみを使っているわけではない。SAやPSと呼ばれる人たちは顧客の要件を深いレベルで理解し、それに基づいたシステム構築を請け負う。

一方、サポートは自社のサービスの使い方の方にフォーカスをおいている。そのため、基本的には自社サービスに関連することを中心に課題を解決する。加えて、コミュニケーションの接点がサポートケースという経路しかない。(重要なケースの場合はSAやPSから情報を共有してもらうこともあるが)。そのためどうしても、点での課題解決となりやすい。

 

サポートへの質問の仕方について

さて上記を踏まえた上でコミュニケーションを円滑にするために必要なことはなんだろうか。

基本的には以下のことだと考えている。

 

  1. 正確な用語を使う
  2. ログを提出する
  3. その他提出するべきものがあればそれを提出する。

 

1. 正確な用語を使う

別に特別な事を要求しているわけではない。ただ、コミュニケーションを円滑にするために正確な用語を使ってほしい。特にありがちなのが、お客様の中での用語をそのまま使ってくる事だ。結局確認の手間が挟まって非効率になりがちである。

 

 

2. ログを提出する

ログを提出してしまうのが大体の場合は解決の近道だ。このとき気をつけてほしいのが、生ログを提出することが。(当然だがパスワードやapikeyなどはマスクしてほしい。)ログがあれば調査ができるが、ログもないとエスパーをするしかない。

 

3. その他提出すべきものがあればそれを提出する

チケット上でサポートから何か求められたらそれをなるべく早い形で提供してあげてほしい。ログだけではわからなかった場合に、サポートは原因と考えられる事について、その他の情報を求める。その情報を速めに提出する事が、ケースの早期解決につながる。

 

まとめ

正直特に特別なことは言っていない。一般的なコミュニケーションの基本だと思う。

本記事によって、皆様が快適なサポート利用術をご利用できる事をお祈りする。