要想快速地将200万个CSV解析并存入MongoDB中,可以使用Bulk()函数(我在Node中尝试过)
首先
-
- 大量のデータを操作するときは Bulk() を使おうという当たり前の話
-
- 言語は別になんでもいいけどなんとなくNode
- 英辞郎のCSVデータ(約 200万件 )をmongoに突っ込んだ時のコードとか。
# コマンド例
node good.js eijiro_dic_utf8.csv
如果不使用Bulk
var fs = require('fs');
var MongoClient = require('mongodb').MongoClient;
var CSV = require('comma-separated-values');
var NAME_MONGO_DB = 'eijiro';
var NAME_MONGO_COLLECTION = 'words';
var url = 'mongodb://localhost:27017/' + NAME_MONGO_DB;
var inputCsv = process.argv[2];
var text = fs.readFileSync(inputCsv, 'utf-8');
// data: example [ {a : 1}, {a : 2}, {a : 3} ]
var insertDocuments = function(db, data, callback) {
// Get the documents collection
var collection = db.collection(NAME_MONGO_COLLECTION);
// Insert some documents
collection.insert(data, function(err, result) {
if (err) return console.error(err);
callback(result);
});
};
MongoClient.connect(url, function(err, db) {
if (err) return console.error(err);
var rows = new CSV(text, { header: true, cast: false }).parse();
insertDocuments(db, rows, function(result) {
db.close();
});
});
- 大体40分くらいかかった気がする。
若使用 Bulk
var fs = require('fs');
var MongoClient = require('mongodb').MongoClient;
var CSV = require('comma-separated-values');
var NAME_MONGO_DB = 'eijiro';
var NAME_MONGO_COLLECTION = 'words';
var url = 'mongodb://localhost:27017/' + NAME_MONGO_DB;
var inputCsv = process.argv[2];
var text = fs.readFileSync(inputCsv, 'utf-8');
MongoClient.connect(url, function(err, db) {
if (err) return console.error(err);
var col = db.collection(NAME_MONGO_COLLECTION);
var batch = col.initializeUnorderedBulkOp();
new CSV(text, { header: true, cast: false }).forEach(function(obj) {
batch.insert(obj);
});
batch.execute(function(err, result) {
db.close();
if (err) console.err(err);
process.exit();
});
});
- 1分もあれば終わる。
关于批量的补充说明
每组操作最多可以有1000个操作。如果一组超过这个限制,MongoDB会将该组分成1000个或更少的较小组。例如,如果批量操作列表包含2000个插入操作,MongoDB会创建2个每个有1000个操作的组。
感想
-
- readFileSync() を使わなければならないのが残念すぎる。
-
- 全部streamっぽく処理できれば良いなぁと思う。( comma-separated-values の同期的な書き方が気持ち悪すぎる)
-
- 最初は、 C2FO/fast-csv を使おうとしたが、parseの際に日本語文字を上手く解釈できずに落ちたので泣く泣く止めた。
- github repository