猫鼬插件不挂钩 findOneAndUpdate
mongoose plugin doesn't hook on findOneAndUpdate
我像这样设置猫鼬模式:
const expertSchema = new mongoose.Schema({
firstName: {
type: String,
required: true,
},
lastName: {
type: String,
required: true,
},
contactMethods: {
type: [ContactMethod.schema],
}
})
expertSchema.plugin(autoIncrement.plugin, {
model: 'EXP-',
startAt: 1,
prefix: 'EXP-'
});
const Expert = mongoose.model('Expert', expertSchema);
const contactMethodsSchema = new mongoose.Schema({
type: {
type: String,
required: true,
},
value: {
type: String,
required: true,
},
preferred: {
type: Boolean
}
});
contactMethodsSchema.plugin(autoIncrement.plugin, {
model: 'CON-',
startAt: 1,
prefix: 'CON-'
});
const ContactMethod = mongoose.model('ContactMethod', contactMethodsSchema)
我使用的是 mongoose-auto-increment plugin to auto-increment my monogodb document's id's (actually using this 分支,但它们基本相同)
我有一些代码可以作为我的开发者的种子。重新启动时的数据库如下所示:
const contMethod1 = new models.ContactMethod({
type: 'email',
value: "janedoe@acme.org",
preferred: false,
});
const contMethod2 = new models.ContactMethod({
type: 'phone',
value: "+12125550711",
preferred: true,
});
const expert1 = new models.Expert({
firstName: 'Jane',
lastName: 'Doe',
contactMethods: [contMethod1, contMethod2]
});
expert1.save();
此代码运行良好,我最终得到的文档如下所示:
{
"_id": "EXP-1",
"firstName": "Jane",
"lastName": "Doe",
"contactMethods": [{
"type": "email",
"value": "janedoe@acme.org",
"preferred": false,
"_id": "CON-1"
},
{
"type": "phone",
"value": "+12125550711",
"preferred": true,
"_id": "CON-2"
}
]
}
然而,当我的前端将编辑后的数据发回给我时,我得到 json 看起来像:
{
_id: "EXP-1",
"contactMethods": [{
"type": "email",
"value": "janedoe@acme.org",
"preferred": false,
"_id": "CON-1"
},
{
"type": "phone",
"value": "+12125550711",
"preferred": true,
"_id": "CON-2"
},
{
"type": "whatsapp",
"value": "+123456789",
"preferred": false
}
]
}
现在我想要的是更新现有的嵌入文档 and/or 如果需要添加新的。我为此目的设置了这段代码(我很欣赏可能有更智能的方法来实现它,但即便如此,它还是有点“有效”):
req.body.contactMethods.map((_, index) => {
if (_._id) {
expert = req.context.models.Expert.findOneAndUpdate({
"contactMethods._id": _._id
}, {
$set: {
"contactMethods.$.type": _.type,
"contactMethods.$.value": _.value,
"contactMethods.$.preferred": _.preferred
}
}, {
useFindAndModify: false,
returnOriginal: false,
runValidators: true
})
} else {
expert = req.context.models.Expert.findOneAndUpdate({
"_id": req.user._id,
}, {
$push: {
"contactMethods": _
}
}, {
useFindAndModify: false,
returnOriginal: false,
runValidators: true
})
}
})
不幸的是,在这种情况下,我的插件没有“触发”或调用,我最终在集合中更新了一个文档,该文档缺少新推送的 contactMethod 的“_id”属性。
为什么我的插件在 findOneAndUpdate 调用中没有被调用?
我找到了 but my plugin doesn't use ES6 syntax. Also I found this comment,但当前的 mongoose 文档不再说明这一点,所以我有点希望他们 changed/fixed 它。
谢谢!
(第一个问题,呸..)
我最终解决了(或者更确切地说是解决了这个问题),方法是更改我的代码并将新联系方法的添加拆分为两个操作:findOne 和保存,如下所示:
req.body.contactMethods.map((_, index) => {
if (_._id) {
expert = req.context.models.Expert.findOneAndUpdate({
"contactMethods._id": _._id
}, {
$set: {
"contactMethods.$.type": _.type,
"contactMethods.$.value": _.value,
"contactMethods.$.preferred": _.preferred
}
}, {
useFindAndModify: false,
returnOriginal: false,
runValidators: true
})
} else {
expert = req.context.models.Expert.findOne({
"_id": req.user._id,
})
expert.contactMethods.push(_);
expert.save({ validateModifiedOnly: true });
}
})
我像这样设置猫鼬模式:
const expertSchema = new mongoose.Schema({
firstName: {
type: String,
required: true,
},
lastName: {
type: String,
required: true,
},
contactMethods: {
type: [ContactMethod.schema],
}
})
expertSchema.plugin(autoIncrement.plugin, {
model: 'EXP-',
startAt: 1,
prefix: 'EXP-'
});
const Expert = mongoose.model('Expert', expertSchema);
const contactMethodsSchema = new mongoose.Schema({
type: {
type: String,
required: true,
},
value: {
type: String,
required: true,
},
preferred: {
type: Boolean
}
});
contactMethodsSchema.plugin(autoIncrement.plugin, {
model: 'CON-',
startAt: 1,
prefix: 'CON-'
});
const ContactMethod = mongoose.model('ContactMethod', contactMethodsSchema)
我使用的是 mongoose-auto-increment plugin to auto-increment my monogodb document's id's (actually using this 分支,但它们基本相同)
我有一些代码可以作为我的开发者的种子。重新启动时的数据库如下所示:
const contMethod1 = new models.ContactMethod({
type: 'email',
value: "janedoe@acme.org",
preferred: false,
});
const contMethod2 = new models.ContactMethod({
type: 'phone',
value: "+12125550711",
preferred: true,
});
const expert1 = new models.Expert({
firstName: 'Jane',
lastName: 'Doe',
contactMethods: [contMethod1, contMethod2]
});
expert1.save();
此代码运行良好,我最终得到的文档如下所示:
{
"_id": "EXP-1",
"firstName": "Jane",
"lastName": "Doe",
"contactMethods": [{
"type": "email",
"value": "janedoe@acme.org",
"preferred": false,
"_id": "CON-1"
},
{
"type": "phone",
"value": "+12125550711",
"preferred": true,
"_id": "CON-2"
}
]
}
然而,当我的前端将编辑后的数据发回给我时,我得到 json 看起来像:
{
_id: "EXP-1",
"contactMethods": [{
"type": "email",
"value": "janedoe@acme.org",
"preferred": false,
"_id": "CON-1"
},
{
"type": "phone",
"value": "+12125550711",
"preferred": true,
"_id": "CON-2"
},
{
"type": "whatsapp",
"value": "+123456789",
"preferred": false
}
]
}
现在我想要的是更新现有的嵌入文档 and/or 如果需要添加新的。我为此目的设置了这段代码(我很欣赏可能有更智能的方法来实现它,但即便如此,它还是有点“有效”):
req.body.contactMethods.map((_, index) => {
if (_._id) {
expert = req.context.models.Expert.findOneAndUpdate({
"contactMethods._id": _._id
}, {
$set: {
"contactMethods.$.type": _.type,
"contactMethods.$.value": _.value,
"contactMethods.$.preferred": _.preferred
}
}, {
useFindAndModify: false,
returnOriginal: false,
runValidators: true
})
} else {
expert = req.context.models.Expert.findOneAndUpdate({
"_id": req.user._id,
}, {
$push: {
"contactMethods": _
}
}, {
useFindAndModify: false,
returnOriginal: false,
runValidators: true
})
}
})
不幸的是,在这种情况下,我的插件没有“触发”或调用,我最终在集合中更新了一个文档,该文档缺少新推送的 contactMethod 的“_id”属性。
为什么我的插件在 findOneAndUpdate 调用中没有被调用?
我找到了
谢谢! (第一个问题,呸..)
我最终解决了(或者更确切地说是解决了这个问题),方法是更改我的代码并将新联系方法的添加拆分为两个操作:findOne 和保存,如下所示:
req.body.contactMethods.map((_, index) => {
if (_._id) {
expert = req.context.models.Expert.findOneAndUpdate({
"contactMethods._id": _._id
}, {
$set: {
"contactMethods.$.type": _.type,
"contactMethods.$.value": _.value,
"contactMethods.$.preferred": _.preferred
}
}, {
useFindAndModify: false,
returnOriginal: false,
runValidators: true
})
} else {
expert = req.context.models.Expert.findOne({
"_id": req.user._id,
})
expert.contactMethods.push(_);
expert.save({ validateModifiedOnly: true });
}
})