2015-11-19 119 views
2

有時候我會創建一個臨時集合來將多個集合中的數據集合到一個集合中進行報告。我需要在創建報告後不久刪除此臨時集合,以避免使用來自多個報告請求的臨時集合填充磁盤空間。MongoDB如何在操作完成後刪除臨時集合

目前我執行這個從應用

db.dropCollection('tempCollection564e1f5a4abea9100523ade5'); 

但每次運行時的結果並不一致。有時候,收集成功下降,但其他時間收集失敗,此錯誤消息砸:

MongoError:異常:無法執行操作:後臺操作當前正在運行的集合databaseName.tempCollectionName
代碼:12587

在MongoDB中刪除臨時集合的最佳做法是什麼?我目前使用UUID命名該集合以避免名稱衝突,並且在我試圖銷燬臨時集合之前,集合僅使用了一次。

有沒有辦法檢查一個集合的操作是否正在進行,然後在操作完成時刪除集合?

note:我不認爲這是在應用程序中的JavaScript異步代碼的問題。聚合查詢完成後,我打電話給dropCollection()

+0

如果插入短暫超時,我可以成功地刪除集合,但這會感到ha。。 – steampowered

+0

你知道該集合上正在運行什麼操作嗎?看起來有點奇怪,聚合完成後會有東西在運行。也許一些索引或什麼? –

回答

0

我最終創建了這個貓鼬插件,它在生產中已經運行了一年多了。我創建了一個臨時集合,然後在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; 
相關問題