gpt4 book ai didi

javascript - findOneAndUpdate 中的文档未更新

转载 作者:IT老高 更新时间:2023-10-28 13:05:38 25 4
gpt4 key购买 nike

我有一个 post 路由,它接收来自 express 应用程序中的 PUT 请求的数据,该应用程序旨在根据提交的表单输入更新 mongoose 文档。 “基本”模型是 Profile,我有两个 discriminatorHelperFinder 建模,它们有条件地将字段添加到 Profile 架构中(详见下文)。

因此,req.body.profile 将根据与其关联的鉴别器包含不同的字段,但始终包含字段(usernameemail city, accountType) 存在于“基本”模型中,Profile

在我发送 PUT 请求之前,Profile 中的文档示例如下所示:

{ jobTitle: '',
lastPosition: '',
email: '',
city: '',
accountType: 'helper',
_id: 5c77883d8db04c921db5f635,
username: 'here2help',
__v: 0 }

这对我来说看起来不错,并表明正在按照我的意愿创建模型(使用来自 Profile 的基本字段,以及与 Helper 模型关联的那些 - 请参阅下面是模型)。

我的 POST 路线如下所示:

router.put("/profile/:id", middleware.checkProfileOwnership, function(req, res){

console.log(req.body.profile);

Profile.findOneAndUpdate(req.params.id, req.body.profile, function(err, updatedProfile){

if(err){
console.log(err.message);
res.redirect("/profile");
} else {
console.log(updatedProfile);
res.redirect("/profile/" + req.params.id);
}

});
});

我从表单 (console.log(req.body.profile)) 收到的信息是我希望看到的:

{ accountType: 'helper',
username: 'here2help',
email: 'helpingU@me.com',
city: 'New York',
jobTitle: 'CEO',
lastPosition: 'sales rep'}

但是,在 Profile.findOneAndUpdate() 中使用 req.body.profile 更新文档后,我没有看到我返回的文档更新:

console.log(updatedProfile)

{ jobTitle: '',
lastPosition: '',
email: 'helpingu@me.com',
city: 'New York',
accountType: 'helper',
_id: 5c77883d8db04c921db5f635,
username: 'here2help',
__v: 0 }

因此,在我的“基本”模型中定义的字段(即在 ProfileSchema 中定义的字段 - 见下文)正在更新(例如 city),但那些在我的鉴别器中不是 - 见下文。

更新的信息清楚地存在于 req 中,但没有传播到 Profile 模型 - 这怎么可能?

我也尝试过使用 findByIdAndUpdate 但我得到了相同的结果。

这是我定义的模式:

个人资料 - 我的“基础”架构:

var mongoose = require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");

var profileSchema = new mongoose.Schema({
username: String,
complete: { type: Boolean, default: false },
email: { type: String, default: "" },
city: { type: String, default: "" }
}, { discriminatorKey: 'accountType' });

profileSchema.plugin(passportLocalMongoose);

module.exports = mongoose.model("Profile", profileSchema);

查找器

var Profile = require('./profile');

var Finder = Profile.discriminator('finder', new mongoose.Schema({
position: { type: String, default: "" },
skills: Array
}));

module.exports = mongoose.model("Finder");

助手

var Profile = require('./profile');

var Helper = Profile.discriminator('helper', new mongoose.Schema({
jobTitle: { type: String, default: "" },
lastPosition: { type: String, default: "" }
}));

module.exports = mongoose.model("Helper");

这是我第一次尝试使用 discriminators在 Mongoose 中,所以很可能是我设置不正确,这是问题的根源。

如果不清楚,请告诉我,或者我需要添加更多信息。

最佳答案

使用什么架构来查询数据库很重要

鉴别器根据您使用的对象构建 mongo 查询。例如,如果您使用 mongoose.set('debug', true) 在 mongo 上启用调试并运行 Profile.findOneAndUpdate(),您应该会看到如下内容:

Mongoose: profiles.findAndModify({
_id: ObjectId("5c78519e61f4b69da677a87a")
}, [], {
'$set': {
email: 'finder@me.com',
city: 'New York',
accountType: 'helper',
username: 'User NAme', __v: 0 } }, { new: true, upsert: false, remove: false, projection: {} })

请注意,它仅使用配置文件架构中定义的字段。

如果你使用 Helper,你会得到类似的东西:

profiles.findAndModify({
accountType: 'helper',
_id: ObjectId("5c78519e61f4b69da677a87a")
}, [], {
'$set': {
jobTitle: 'CTO',
email: 'finder@me.com',
city: 'New York',
accountType: 'helper ',
username: 'User Name', __v: 0 } }, { new: true, upsert: false, remove: false, projection: {} })

注意它在过滤条件中添加了鉴别器字段,这是documented :

Discriminator models are special; they attach the discriminator key to queries. In other words, find(), count(), aggregate(), etc. are smart enough to account for discriminators.

所以更新时需要做的是使用鉴别器字段,以便在调用更新语句时知道使用哪个Schema:

app.put("/profile/:id", function(req, res){
console.log(req.body);

if(ObjectId.isValid(req.params.id)) {

switch(req.body.accountType) {
case 'helper':
schema = Helper;
break;
case 'finder':
schema = Finder;
break;
default:
schema = Profile;
}

schema.findOneAndUpdate({ _id: req.params.id }, { $set : req.body }, { new: true, upsert: false, remove: {}, fields: {} }, function(err, updatedProfile){
if(err){
console.log(err);
res.json(err);
} else {
console.log(updatedProfile);
res.json(updatedProfile);
}

});
} else {
res.json({ error: "Invalid ObjectId"});
} });

请注意,在创建新文档时不需要上述内容,在这种情况下 mongoose 能够确定要使用哪个鉴别器。

您无法更新鉴别器字段

上述行为有副作用,您无法更新鉴别器字段,因为它不会找到记录。在这种情况下,您需要直接访问集合并更新文档,并定义属于另一个鉴别器的字段会发生什么。

db.profile.findOneAndUpdate({ _id: req.params.id }, { $set : req.body }, { new: true, upsert: false, remove: {}, fields: {} }, function(err, updatedProfile){
if(err) {
res.json(err);
} else {
console.log(updatedProfile);
res.json(updatedProfile);
}
});

关于javascript - findOneAndUpdate 中的文档未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54892850/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com