有时我会创建一个临时集合,将多个集合中的数据聚合到一个集合中进行报告。我需要在创建报告后立即删除此临时集合,以避免使用来自许多报告请求的临时集合填满磁盘空间。
目前我从应用程序
执行此操作db.dropCollection('tempCollection564e1f5a4abea9100523ade5');
但每次运行时结果都不一致。有时集合会成功删除,但有时集合无法删除此错误消息:
MongoError:exception:无法执行操作:当前正在为集合databaseName.tempCollectionName运行后台操作
代码:12587
在MongoDB中删除临时集合的最佳做法是什么?我目前使用UUID命名该集合以避免名称冲突,并且该集合仅在我尝试销毁临时集合之前使用一次。
有没有办法检查集合的操作是否正在进行,然后在操作完成时删除集合?
注意:我不相信这是应用程序中的javascript异步代码的问题。我在聚合查询完成后调用dropCollection()
。
答案 0 :(得分:0)
我最终创建了这个mongoose插件,并且它已经在生产中运行了一年多。我创建了一个临时集合,然后在1分钟后使用setTimeout()
删除集合。 1分钟足以查询集合,因此集合不再使用。
这会创建具有唯一名称的集合,例如z_tempCollection_595820e4ae61ecc89635f794
,因此永远不会发生名称冲突。
var mongoose = require('mongoose');
var _ = require('lodash');
var util1 = require(global.appRootPath + '/lib/util1_lib.js');
function tempCollection(persistantSchema){
persistantSchema.statics.resultIntoTempCollection = function (tempCollectionDataArray, options, callback) {
var timestampSeconds = Math.round(Date.now() / 1000);
var tmpCollectionName = 'z_tempCollection_' + (new mongoose.mongo.ObjectId().toString()) + '_' + timestampSeconds;
var registeredModelName = 'tempModel' + tmpCollectionName;
options = options || {};
options.strict = _.isUndefined(options.strict) ? false : options.strict;
options.schema = _.isUndefined(options.schema) ? {} : options.schema;
var tmpSchema = new mongoose.Schema(options.schema, {strict: options.strict, collection: tmpCollectionName});
tmpSchema.statics.removeTempCollection = function(tempModel){
var maxRemovalAttempts = 3;
delete mongoose.models[registeredModelName];
delete mongoose.modelSchemas[registeredModelName];
setTimeout(function(){
mongoose.connection.db.dropCollection(tmpCollectionName, function (err, result) {
if (err) {
util1.saveError(err, 'server', null);
}
});
}, 60 * 1000);
}
// tempModel variable ref is overwritten on each subsequent run of resultIntoTempCollection
var tempModel = mongoose.model(registeredModelName, tmpSchema);
var promises = [];
tempCollectionDataArray.forEach(function(doc){
promises.push(new tempModel(doc).save());
});
return Promise.all(promises).then(function(){
return tempModel;
});
}
}
module.exports = tempCollection;