2017-10-07 205 views
0

的部分更新我有一个简单的用户模式:猫鼬对象

{ 
    _id: "59d72070d9d03b28934b972b" 
    firstName: "first" 
    lastName: "last" 
    email: "[email protected]" 
    subscriptions: { 
    newsletter: true, 
    blog: true 
    } 
} 

我试图做subscriptions对象的部分更新。我传递了用户的id和一个可以具有对象的一个​​或两个属性的对象。假设我只想更新newsletter并将其设置为false。我会送:

{ id: "59d72070d9d03b28934b972b", payload: { newsletter: false } } 

然后:

const user = await User.findByIdAndUpdate(
    args.id, 
    { $set: { subscriptions: args.payload } }, 
    { upsert: true, new: true } 
); 

这将返回:

subscriptions: { 
    newsletter: false 
} 

有没有办法只能修改newsletter属性时,我只在通过newsletter有效载荷对象而不删除其他属性?我知道在这个例子中我只有两个属性,但是随着时间的推移,对象将不断扩展。

回答

0

最后我做了以下内容:

const user = await User.findById(args.id); 

// merge subscriptions 
user.subscriptions = Object.assign({}, user.subscriptions, args.payload); 

return user.save(); 
+0

这将工作,但会执行2个请求:1'users.findOne'和1'users.update',而最初只有1个'users.findAndModify' –

0

仅更新嵌套的字段,使用{ "subscriptions.newsletter": false }

const user = (await User.findByIdAndUpdate(
    args.id, { 
     $set: { 
      "subscriptions.newsletter": args.payload 
     } 
    }, { 
     new: true 
    } 
)); 

如果你的输入可以有缺失的领域,你可以在$set建立一个动态查询,只有你在你的输入指定的字段:

async function save(id, query) { 
    const user = (await User.findByIdAndUpdate(
     id, { 
      $set: query 
     }, { 
      new: true 
     } 
    )); 
    console.log(user); 
} 

var id = mongoose.Types.ObjectId("59d91f1a06ecf429c8aae221"); 
var input = { 
    newsletter: false, 
    blog: false 
}; 

var query = {}; 
for (var key in input) { 
    query["subscriptions." + key] = input[key]; 
} 

save(id, query);