我正在尝试更新一个子文档addresses
(有效),然后更新除上一个子文档以外的许多子文档。基本上,每次address
将is_preferred
更改为true时,都必须将is_preferred
是true
的先前地址更新为false
(我正在尝试更新所有人除了更改为true的地址)。
用户文档
_id: ObjectId("5b996f0fd5fbf511709f668f");
addresses: [
{
_id: ObjectId("5ba33e0991cd7a3bb85dab7e");
is_preferred:true
},
{
_id: ObjectId("5ba3e9337310c637207b44cb");
is_preferred:false
}
]
这是我的解决方法:
// model
User = mongoose.model('user', new Schema({
_id: { type: mongoose.Schema.Types.ObjectId, required: true },
addresses: [
{
_id: { type: mongoose.Schema.Types.ObjectId, required: true },
is_preferred: { type: Boolean, required: true }
}
],
}, { collection: 'user' }););
// route
router.put('/updateAddress/:addressId', auth, user.updateAddress);
// user.js
exports.updateAddress = wrap(async(req, res, next) => {
// update one object address `is_preferred` to true and return an array 'addresses' containing it
const user = await User.findOneAndUpdate(
{ addresses: { $elemMatch: { _id: mongoose.Types.ObjectId(req.params.addressId) } } }, { 'addresses.$': req.body },
{ projection: {
addresses: {
$elemMatch: { _id: mongoose.Types.ObjectId(req.params.addressId) }
}
}, new: true }).lean();
if (user) {
// updated object `is_preferred` changed to true, so another objects must be false
if (user.addresses[0].is_preferred) {
// doesnt work
await User.update({ _id: { $ne: mongoose.Types.ObjectId(req.params.addressId) }, is_preferred: true },
{ $set: { addresses: { is_preferred: false } } }, { multi: true });
}
res.status(200).json({success: true, message: 'Saved.', new_object: user.addresses[0]});
} else {
res.status(400).json({success: false, message: 'Error.'});
}
});
我能够将user
子文档addresses
is_preferred
更新为true
。但是,将另一个addresses
is_preferred
更新为false
无效。我究竟做错了什么?
答案 0 :(得分:0)
对于像您这样的场景,我建议您使用猫鼬中间件let multiLineString = """
Line One
Line Two
Line Three
"""
或pre
模式挂钩。这个想法是,与其在您的控制器中处理该问题,不如通过该中间件在您的模式中进行处理。
唯一的不便之处是post
和pre
钩子不会在post
上触发,因此您需要先执行findOneAndUpdate
然后执行find
。 / p>
因此,您将对update
挂钩执行以下操作:
post
要使更新生效,您需要执行以下操作:
User.post('save', doc => {
// You can update all the rest of the addresses here.
});