mlabでホストされているMongoDBからgoogle bigqueryにデータをエクスポートする最適な方法は何ですか?MongoDB to BigQuery
最初は、MongoDBからBigQueryに1回の読み込みを実行しようとしていますが、後でbigqueryへのリアルタイムデータフローにPub/Subを使用することを考えています。
私はmongodbからbigqueryまでの最初の1回の読み込みで助けが必要です。
mlabでホストされているMongoDBからgoogle bigqueryにデータをエクスポートする最適な方法は何ですか?MongoDB to BigQuery
最初は、MongoDBからBigQueryに1回の読み込みを実行しようとしていますが、後でbigqueryへのリアルタイムデータフローにPub/Subを使用することを考えています。
私はmongodbからbigqueryまでの最初の1回の読み込みで助けが必要です。
MongoDBのドキュメントの基本的な解説から、mongoexport
を使用してデータベースをJSONとしてダンプできるようです。これを済ませたら、JSONファイルをGCSにコピーした後にJSONファイルからテーブルを作成する方法については、BigQuery loading dataトピックを参照してください。
私の意見では、ベストプラクティスは独自のエクストラクタを構築することです。これはあなたの選択した言語で行うことができ、あなたは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に簡単にロードできます。
日付フィールドはどうですか?日付/時刻フィールドにデータをエクスポートすると「$ date」のように表示され、BigQueryのフィールド名では受け入れられません。このための回避策はありますか? – Qorbani
私は残念なことに、まず名前を変更する必要があると思います。 –
エリオットありがとう、私はそれを修正する方法を見つけ、この質問に別の答えとしてそれを提出します。これは将来私のような人を助けるかもしれません:-) – Qorbani