文档中删除数组元素并保存

在模型文档中有一个数组。我想根据我提供的键删除数组中的元素,然后更新 MongoDB。这可能吗?

下面是我的尝试:

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

So far it finds the document but the remove nor save works.

173106 次浏览

Since favorites is an array, you just need to splice it off and save the document.

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

选中的答案确实有效,但是在 MongoooseJS 的最新版本中,您应该使用

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

Https://mongoosejs.com/docs/api.html#mongoosearray_mongoosearray-pull

我也正在查。

看看丹尼尔对正确答案的回答,好多了。

您还可以直接在 MongoDB 中执行更新,而不必加载文档并使用代码对其进行修改。使用 $pull$pullAll运算符从数组中删除该项:

Favorite.updateOne({ cn: req.params.name }, {
$pullAll: {
favorites: req.params.deleteUid,
},
});

然后从数组中删除对象

Favorite.updateOne({ cn: req.params.name }, {
$pullAll: {
favorites: [{_id: req.params.deleteUid}],
},
});

(也可以对多个文档使用 updateMany)

Http://docs.mongodb.org/manual/reference/operator/update/pullall/

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';; :)

这对我很有用,真的很有帮助。

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的模型,我想从这个类别数组中删除优惠券。我有一个类别的数组,所以我使用了 arrOfSubCategory。因此,我用映射函数借助于 $in运算符从这个数组中提取每个对象数组。

上面的答案显示了如何删除数组,这里是如何从数组中提取对象。

参考资料: https://docs.mongodb.com/manual/reference/operator/update/pull/

db.survey.update( // select your doc in moongo
{ }, // your query, usually match by _id
{ $pull: { results: { $elemMatch: { score: 8 , item: "B" } } } }, // item(s) to match from array you want to pull/remove
{ multi: true } // set this to true if you want to remove multiple elements.
)

我在我的项目中使用了这种格式,并且成功了

router.delete('/dashboard/participant/:id', async (req, res, next) => {
try {
const participant = await Participant.findByIdAndDelete({ _id: req.params.id });
// { $pull: { templates: { _id: templateid } } },
const event = await Event.findOneAndUpdate({ participants: participant._id }, { $pull: { participants: participant._id } }, { new: true });
res.status(200).json({ request: 'Deleted', participant, event });
} catch (error) {
res.json(error)
}
});
Favorite.update({ cn: req.params.name }, { "$pull": { "favorites": { "_id": favoriteId } }}, { safe: true, multi:true }, function(err, obj) {
//do something smart
});