Goで数値を文字列にする方法
strconvで変換する。
import ( "fmt" "strconv" ) func subtractProductAndSum(n int) int { sum, prod := 0, 1 for _, x := range fmt.Sprintf("%d", n) { xi, _ := strconv.Atoi(string(x)) sum += xi prod *= xi } return prod - sum }
Golangで配列内の重複する値を調べる方法
辞書型のデータを作って、Keyに配列の値をいれる。 それをforでincrementしたらそれぞれが何個入っているかがわかる。
func repeatedNTimes(A []int) { list:= make(map[int]int) ln:=len(A) for _, val:=range A { list[val]++ } } fmt.Println(list) }
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種類が存在する。
- Streaming Import
- Bulk import
Streaming Importってなに
fluentdやjs-sdkなどを利用して、リアルタイムで生成されているデータを転送する方法。 1回あたりにインポートされるレコード数も少ない
Bulk Importってなに
DBのテーブルなどの大きなデータをまとめて、転送する方法。
今回の記事では2のBulk Importについて話をする。
Treasure Dataで利用できるBulk Importの種類について
大まかに以下の3つの方法が存在する。
- DataConnector
- Bulk import(Embulk)
- 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. ログを提出する
ログを提出してしまうのが大体の場合は解決の近道だ。このとき気をつけてほしいのが、生ログを提出することが。(当然だがパスワードやapikeyなどはマスクしてほしい。)ログがあれば調査ができるが、ログもないとエスパーをするしかない。
3. その他提出すべきものがあればそれを提出する
チケット上でサポートから何か求められたらそれをなるべく早い形で提供してあげてほしい。ログだけではわからなかった場合に、サポートは原因と考えられる事について、その他の情報を求める。その情報を速めに提出する事が、ケースの早期解決につながる。
まとめ
正直特に特別なことは言っていない。一般的なコミュニケーションの基本だと思う。
本記事によって、皆様が快適なサポート利用術をご利用できる事をお祈りする。