2013-02-08 7 views
24

Tôi có một mảng trong tài liệu mô hình của mình. Tôi muốn xóa các phần tử trong mảng đó dựa trên khóa mà tôi cung cấp và sau đó cập nhật MongoDB. Điều này có thể không?Mongoose xóa phần tử mảng trong tài liệu và lưu

Đây là nỗ lực của tôi:

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(); 
     }); 
    }); 
}; 

Cho đến nay nó tìm thấy các tài liệu nhưng cũng không loại bỏ lưu công trình.

Trả lời

51

Bạn cũng có thể thực hiện cập nhật trực tiếp trong MongoDB mà không phải tải tài liệu và sửa đổi nó bằng mã. Sử dụng các $pull hoặc $pullAll nhà khai thác để loại bỏ các mục từ mảng:

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

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

+2

Điều này là tốt hơn cho hiệu suất. –

+1

Rất hữu ích, cảm ơn. – Nate

+1

Cảm ơn bạn .. đã làm việc – Dibish

5

Vì mục yêu thích là một mảng, bạn chỉ cần ghép nó ra và lưu tài liệu.

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

Cảm ơn bạn đã phản hồi rất kỹ lưỡng. – occasl

+3

nếu bạn cố gắng xóa 2 thứ cùng một lúc, cả hai đều có thể nhận được mảng, sau đó thay đổi nó và thay đổi đầu tiên được lưu sẽ bị ghi đè bởi lần thứ hai. Tôi thà đi với sth như thế này http://stackoverflow.com/questions/16959099/how-to-remove-array-element-in-mongodb. – Maximosaic

29

Câu trả lời kiểm tra không làm việc nhưng chính thức trong MongooseJS mới nhất, bạn nên sử dụng kéo.

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

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

Tôi đã chỉ nhìn thấy quá.

Xem câu trả lời chính xác của Daniel. Tốt hơn nhiều.

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 

nếu bạn muốn sử dụng ... bạn nên gọi 'use strict'; ở phía trên cùng của file js của bạn; :)

1

Điều này phù hợp với tôi và thực sự rất hữu ích.

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 
      }) 
     } 
    }) 
}); 

Tôi có mô hình có tên là SubCategory và tôi muốn xóa Phiếu giảm giá khỏi danh mục này Array. Tôi có một loạt các danh mục vì vậy tôi đã sử dụng arrOfSubCategory. Vì vậy, tôi lấy từng mảng đối tượng từ mảng này với chức năng bản đồ với sự trợ giúp của toán tử $in.