我正在尝试使用新的mongo bulk apis编写自定义批量上传脚本。我使用的UnorderedBulkOp
最初起作用非常快,但在被多次调用后它开始挂起。我尝试过使用日志行,似乎在第10次通话之后它真的开始爆炸了。如果我停止上传并重新启动它(有适当的代码来检查欺骗),那么前几次调用execute
会再次执行,因此它似乎不依赖于金额我的收藏中的数据。到底是怎么回事?我想把所有操作都推到批量操作系统并只调用执行一次,但是在这里看到另一个答案,在批量操作上逐步调用execute
。
剥离了一下它正在这样做:
this.db.collection(collection_name, function(err, collection){
var bulk = collection.initializeUnorderedBulkOp();
var operations = 0;
var dataread = fs.createReadStream(filepath, {encoding: 'utf8'});
var current = '';
// load and split data from CSV
dataread.on('data', function(data){
dataread.pause();
chunk = current + data;
var split = chunk.split('\n');
current = split.pop();
var ids = [];
for(i=0, len = split.length; i< len; i++){
lineData = split[i].split(',');
customid = parseInt(lineData[0]);
ids.push(customid);
}
// find which docs already exist and need to be updated
collection.find({customid: {$in: ids}}).toArray(function(err, docs){
var docmap = {};
for(i=0, len=docs.length; i<len; i++){
docmap[docs[i].customid] = docs[i];
}
for(isplit=0; isplit<split.length; isplit++){
lineData = split[isplit].split(',');
customid = parseInt(lineData[0]);
// check for insert or update
if(docmap[customid]){
doc = docmap[customid];
//update doc
bulk.find({_id: doc._id}).update({$push: {history: 1}});
else{
doc = formatData(lineData);
bulk.insert(doc);
}
operations++;
}
if(operations > 10000){
bulk.execute({w: 1}, function(err, result){
operations = 0;
dataread.resume();
});
}else{
dataread.resume();
}
});
});
});
最初我是使用对collection.save
的单独调用来执行此操作,但我的数据集目前大约有200万个数据点,我希望优化,因为我将每周运行一次此上传。
答案 0 :(得分:0)
所以这似乎是批量操作的缺点。虽然它处理顺序批量操作,但单个BulkOp对象最适合仅处理单个批处理过程。我设法通过在成功bulk
次调用的回调中重新初始化execute
来解决此问题。
bulk.execute({w: 1}, function(err, result){
operations = 0;
bulk = collection.initializeUnorderedBulkOp();
dataread.resume();
});