MongoDB如何在操作完成后删除临时集合

时间:2015-11-19 19:35:28

标签: mongodb

有时我会创建一个临时集合,将多个集合中的数据聚合到一个集合中进行报告。我需要在创建报告后立即删除此临时集合,以避免使用来自许多报告请求的临时集合填满磁盘空间。

目前我从应用程序

执行此操作
db.dropCollection('tempCollection564e1f5a4abea9100523ade5');

但每次运行时结果都不一致。有时集合会成功删除,但有时集合无法删除此错误消息:

MongoError:exception:无法执行操作:当前正在为集合databaseName.tempCollectionName运行后台操作
代码:12587

在MongoDB中删除临时集合的最佳做法是什么?我目前使用UUID命名该集合以避免名称冲突,并且该集合仅在我尝试销毁临时集合之前使用一次。

有没有办法检查集合的操作是否正在进行,然后在操作完成时删除集合?

注意:我不相信这是应用程序中的javascript异步代码的问题。我在聚合查询完成后调用dropCollection()

1 个答案:

答案 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;