2017-02-10 12 views
6

Cách tốt nhất để xuất dữ liệu từ MongoDB được lưu trữ trong mlab thành google bigquery là gì?MongoDB to BigQuery

Ban đầu, tôi đang cố gắng tải một lần từ MongoDB lên BigQuery và sau đó tôi đang nghĩ đến việc sử dụng Pub/Sub cho luồng dữ liệu thời gian thực cho truy vấn lớn.

Tôi cần trợ giúp với lần tải đầu tiên từ mongodb lên bigquery.

Trả lời

2

Từ đọc cơ bản tài liệu MongoDB, có vẻ như bạn có thể sử dụng mongoexport để đổ cơ sở dữ liệu của mình dưới dạng JSON. Khi bạn đã hoàn thành, hãy tham khảo chủ đề BigQuery loading data để biết mô tả về cách tạo bảng từ tệp JSON sau khi sao chép chúng vào GCS.

+0

Làm thế nào về trường Ngày? Khi tôi xuất dữ liệu sang trường ngày/giờ hiển thị như "$ date" không được chấp nhận cho tên trường BigQuery. Có cách giải quyết nào cho vấn đề này không? – Qorbani

+0

Tôi nghĩ bạn sẽ cần phải đổi tên chúng bằng cách nào đó đầu tiên, thật không may. –

+0

Cảm ơn bạn Elliott, tôi tìm cách sửa lỗi và gửi nó như một câu trả lời khác cho câu hỏi này có thể giúp một người như tôi trong tương lai :-) – Qorbani

7

Theo ý kiến ​​của tôi, cách tốt nhất là tạo bộ giải nén của riêng bạn. Điều đó có thể được thực hiện bằng ngôn ngữ bạn chọn và bạn có thể trích xuất sang CSV hoặc JSON.

Nhưng nếu bạn đang tìm kiếm một cách nhanh chóng và nếu dữ liệu của bạn không lớn và có thể vừa với một máy chủ thì tôi khuyên bạn nên sử dụng mongoexport. Giả sử bạn có một cấu trúc tài liệu đơn giản như dưới đây:

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

Sau đó, bạn cần phải xác định BigQuery Schema của bạn (mongodb_schema.json) như:

$ 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 

Bây giờ, phần thú vị bắt đầu :-) Extracting dữ liệu dưới dạng JSON từ MongoDB của bạn. Giả sử bạn có một cụm với tên bộ bản sao statuses, db của bạn là sample và bộ sưu tập của bạn là 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 

Như bạn có thể thấy ở trên, tôi giới hạn bạn chạy mẫu và tải lên BigQuery trước khi thực hiện cho tất cả dữ liệu của bạn. Sau khi chạy lệnh trên, bạn sẽ có dữ liệu mẫu của mình trong sample.json NHƯNG có một trường $date sẽ khiến bạn tải lỗi lên BigQuery. Để khắc phục điều đó chúng ta có thể sử dụng sed để thay thế họ tên trường đơn giản:

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

Bây giờ bạn có thể nén, tải lên Google Cloud Storage (GCS) và sau đó tải để BigQuery sử dụng lệnh sau:

# 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" 

Nếu mọi thứ đều ổn, sau đó quay lại và xóa --limit 100000 từ mongoexport lệnh và chạy lại các lệnh trên một lần nữa để tải mọi thứ thay vì mẫu 100k.

THAY THẾ SOLUTION:

Nếu bạn muốn biết thêm tính linh hoạt và hiệu suất không phải là mối quan tâm của bạn, sau đó bạn có thể sử dụng công cụ mongo CLI là tốt. Bằng cách này, bạn có thể viết logic trích xuất của mình trong JavaScript và thực thi nó dựa trên dữ liệu của bạn và sau đó gửi đầu ra tới BigQuery. Dưới đây là những gì tôi đã làm cho quá trình tương tự nhưng sử dụng Javascript để đầu ra trong CSV để tôi có thể tải nó dễ dàng hơn để BigQuery:

# 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: Trong kịch bản ở trên tôi đã lừa nhỏ bằng đường ống đầu ra để có thể chia đầu ra thành nhiều tệp với tiền tố sample_. Ngoài ra trong quá trình chia, nó sẽ GZip đầu ra để bạn có thể tải nó dễ dàng hơn với GCS.

Các vấn đề liên quan