2017-02-10 16 views
6

mlabでホストされているMongoDBからgoogle bigqueryにデータをエクスポートする最適な方法は何ですか?MongoDB to BigQuery

最初は、MongoDBからBigQueryに1回の読み込みを実行しようとしていますが、後でbigqueryへのリアルタイムデータフローにPub/Subを使用することを考えています。

私はmongodbからbigqueryまでの最初の1回の読み込みで助けが必要です。

答えて

2

MongoDBのドキュメントの基本的な解説から、mongoexportを使用してデータベースをJSONとしてダンプできるようです。これを済ませたら、JSONファイルをGCSにコピーした後にJSONファイルからテーブルを作成する方法については、BigQuery loading dataトピックを参照してください。

+0

日付フィールドはどうですか?日付/時刻フィールドにデータをエクスポートすると「$ date」のように表示され、BigQueryのフィールド名では受け入れられません。このための回避策はありますか? – Qorbani

+0

私は残念なことに、まず名前を変更する必要があると思います。 –

+0

エリオットありがとう、私はそれを修正する方法を見つけ、この質問に別の答えとしてそれを提出します。これは将来私のような人を助けるかもしれません:-) – Qorbani

7

私の意見では、ベストプラクティスは独自のエクストラクタを構築することです。これはあなたの選択した言語で行うことができ、あなたはCSVまたはJSONに抽出することができます。

しかし、あなたのデータが巨大でなく、1つのサーバーに収まる場合は、mongoexportを使用することをお勧めします。あなたは、以下のような簡単な文書構造を持っていると仮定しましょう:

{ 
    "_id" : "tdfMXH0En5of2rZXSQ2wpzVhZ", 
    "statuses" : [ 
     { 
      "status" : "dc9e5511-466c-4146-888a-574918cc2534", 
      "score" : 53.24388894 
     } 
    ], 
    "stored_at" : ISODate("2017-04-12T07:04:23.545Z") 
} 

次に、あなたのようなあなたのBigQueryのスキーマ(mongodb_schema.json)を定義する必要があります。

$ cat > mongodb_schema.json <<EOF 
[ 
    { "name":"_id", "type": "STRING" }, 
    { "name":"stored_at", "type": "record", "fields": [ 
     { "name":"date", "type": "STRING" } 
    ]}, 
    { "name":"statuses", "type": "record", "mode": "repeated", "fields": [ 
     { "name":"status", "type": "STRING" }, 
     { "name":"score", "type": "FLOAT" } 
    ]} 
] 
EOF 

さて、楽しい部分が抽出:-)を開始あなたのMongoDBからのJSONとしてのデータ。レプリカセット名がstatuses、dbがsample、コレクションがstatusのクラスタがあるとします。

mongoexport \ 
    --host statuses/db-01:27017,db-02:27017,db-03:27017 \ 
    -vv \ 
    --db "sample" \ 
    --collection "status" \ 
    --type "json" \ 
    --limit 100000 \ 
    --out ~/sample.json 

あなたが上見ることができるように私はすべてのデータのためにそれを行う前にBigQueryにあなたがサンプルとロードを実行するお勧めしますので、私は100Kのレコードに出力を制限します。上記のコマンドを実行した後、サンプルデータはsample.jsonにあるはずですが、$dateというフィールドがあり、BigQueryに読み込む際にエラーが発生します。私たちは、単純なフィールド名にそれらを交換するためにsedを使用できることを修正するには:

# Fix Date field to make it compatible with BQ 
sed -i 's/"\$date"/"date"/g' sample.json 

今、あなたは、圧縮Googleクラウドストレージ(GCS)にアップロードし、次のコマンドを使用したBigQueryにロードできます。

# Compress for faster load 
gzip sample.json 

# Move to GCloud 
gsutil mv ./sample.json.gz gs://your-bucket/sample/sample.json.gz 

# Load to BQ 
bq load \ 
    --source_format=NEWLINE_DELIMITED_JSON \ 
    --max_bad_records=999999 \ 
    --ignore_unknown_values=true \ 
    --encoding=UTF-8 \ 
    --replace \ 
    "YOUR_DATASET.mongodb_sample" \ 
    "gs://your-bucket/sample/*.json.gz" \ 
    "mongodb_schema.json" 

すべてが正常だった場合は、mongoexportコマンドから--limit 100000を削除し、上記のコマンドを再度実行して、100kサンプルではなくすべてをロードします。

ALTERNATIVEソリューション:

あなたはより多くの柔軟性とパフォーマンスがあなたの問題ではないしたい場合は、あなたにもmongo CLIツールを使用することができます。この方法で、抽出ロジックをJavaScriptに書き込んでデータに対して実行し、出力をBigQueryに送信することができます。ここで私は、同じプロセスのためにやったが、私はBigQueryのにはるかに簡単にそれをロードすることができCSVで出力するためにJavaScriptを使用したものである:

# Export Logic in JavaScript 
cat > export-csv.js <<EOF 
var size = 100000; 
var maxCount = 1; 
for (x = 0; x < maxCount; x = x + 1) { 
    var recToSkip = x * size; 
    db.entities.find().skip(recToSkip).limit(size).forEach(function(record) { 
     var row = record._id + "," + record.stored_at.toISOString();; 
     record.statuses.forEach(function (l) { 
      print(row + "," + l.status + "," + l.score) 
     }); 
    }); 
} 
EOF 

# Execute on Mongo CLI 
_MONGO_HOSTS="db-01:27017,db-02:27017,db-03:27017/sample?replicaSet=statuses" 
mongo --quiet \ 
    "${_MONGO_HOSTS}" \ 
    export-csv.js \ 
    | split -l 500000 --filter='gzip > $FILE.csv.gz' - sample_ 

# Load all Splitted Files to Google Cloud Storage 
gsutil -m mv ./sample_* gs://your-bucket/sample/ 

# Load files to BigQuery 
bq load \ 
    --source_format=CSV \ 
    --max_bad_records=999999 \ 
    --ignore_unknown_values=true \ 
    --encoding=UTF-8 \ 
    --replace \ 
    "YOUR_DATASET.mongodb_sample" \ 
    "gs://your-bucket/sample/sample_*.csv.gz" \ 
    "ID,StoredDate:DATETIME,Status,Score:FLOAT" 

TIP:上記のスクリプトでは、私がすることが可能に配管出力により、小さなトリックをしましたプレフィックスはsample_の複数のファイルに分割します。また、分割中に出力をGZipしますので、GCSに簡単にロードできます。