2013-02-08 56 views
24

我的模型文檔中有一個數組。我想根據我提供的密鑰刪除該數組中的元素,然後更新MongoDB。這可能嗎?Mongoose刪除文檔中的數組元素並保存

這裏是我的嘗試:

var mongoose = require('mongoose'), 
    Schema = mongoose.Schema; 

var favorite = new Schema({ 
    cn: String, 
    favorites: Array 
}); 

module.exports = mongoose.model('Favorite', favorite, 'favorite'); 

exports.deleteFavorite = function (req, res, next) { 
    if (req.params.callback !== null) { 
     res.contentType = 'application/javascript'; 
    } 
    Favorite.find({cn: req.params.name}, function (error, docs) { 
     var records = {'records': docs}; 
     if (error) { 
      process.stderr.write(error); 
     } 
     docs[0]._doc.favorites.remove({uid: req.params.deleteUid}); 

     Favorite.save(function (error, docs) { 
      var records = {'records': docs}; 
      if (error) { 
       process.stderr.write(error); 
      } 
      res.send(records); 

      return next(); 
     }); 
    }); 
}; 

到目前爲止發現的文件,但移除也不會保存作品。

回答

51

您也可以直接在MongoDB中進行更新,而無需加載文檔並使用代碼進行修改。使用$pull$pullAll運營商從數組中刪除的項目:

Favorite.update({cn: req.params.name}, { $pullAll: {uid: [req.params.deleteUid] } }) 

http://docs.mongodb.org/manual/reference/operator/update/pullAll/

+2

這對性能來說更好。 –

+1

非常有幫助,謝謝。 – Nate

+1

謝謝你的工作 – Dibish

5

由於收藏夾是一個數組,因此您只需將其拼接並保存文檔即可。

var mongoose = require('mongoose'), 
    Schema = mongoose.Schema; 

var favorite = new Schema({ 
    cn: String, 
    favorites: Array 
}); 

module.exports = mongoose.model('Favorite', favorite); 

exports.deleteFavorite = function (req, res, next) { 
    if (req.params.callback !== null) { 
     res.contentType = 'application/javascript'; 
    } 
    // Changed to findOne instead of find to get a single document with the favorites. 
    Favorite.findOne({cn: req.params.name}, function (error, doc) { 
     if (error) { 
      res.send(null, 500); 
     } else if (doc) { 
      var records = {'records': doc}; 
      // find the delete uid in the favorites array 
      var idx = doc.favorites ? doc.favorites.indexOf(req.params.deleteUid) : -1; 
      // is it valid? 
      if (idx !== -1) { 
       // remove it from the array. 
       doc.favorites.splice(idx, 1); 
       // save the doc 
       doc.save(function(error) { 
        if (error) { 
         console.log(error); 
         res.send(null, 500); 
        } else { 
         // send the records 
         res.send(records); 
        } 
       }); 
       // stop here, otherwise 404 
       return; 
      } 
     } 
     // send 404 not found 
     res.send(null, 404); 
    }); 
}; 
+0

謝謝你的迴應。 – occasl

+3

如果您嘗試同時刪除2件東西,則它們都可能會得到該數組,然後將其更改,並且第一次保存的更改會被第二次覆蓋。我寧願像這樣http://stackoverflow.com/questions/16959099/how-to-remove-array-element-in-mongodb。 – Maximosaic

29

選中的答案的工作,但正式MongooseJS最新的,你應該使用

doc.subdocs.push({ _id: 4815162342 }) // added 
doc.subdocs.pull({ _id: 4815162342 }) // removed 

http://mongoosejs.com/docs/api.html#types_array_MongooseArray-pull

我只是在尋找的是太多。

查看Daniel的正確答案的答案。好多了。

0
keywords = [1,2,3,4]; 
doc.array.pull(1) //this remove one item from a array 
doc.array.pull(...keywords) // this remove multiple items in a array 

,如果你想使用...你應該在你的js文件的頂部調用'use strict';; :)

1

這對我而言非常有幫助。

SubCategory.update({ _id: { $in: 
     arrOfSubCategory.map(function (obj) { 
      return mongoose.Types.ObjectId(obj); 
     }) 
    } }, 
    { 
     $pull: { 
      coupon: couponId, 
     } 
    }, { multi: true }, function (err, numberAffected) { 
     if(err) { 
      return callback({ 
       error:err 
      }) 
     } 
    }) 
}); 

我有一個模型,它的名字是SubCategory,我想從這一類Array中優惠券。我有一系列的類別,所以我使用了arrOfSubCategory。所以我用$in運算符的幫助下,用map函數從這個數組中取出每個對象數組。