使用键访问和更新mongo对象

时间:2017-04-21 12:04:37

标签: javascript node.js mongodb object mongoose

我有一个mongo架构,如下所示

var schema = mongoose.Schema({
user: {type:ObjectId, ref: 'User'},
preferences: mongoose.Schema.Types.Mixed
});

module.exports = mongoose.model('UserPreference', schema);

我正在使用数据进行调查

{
"newQuestionPrompt": false,
"oldQuestion": false
}

每个属性都需要设置到首选项字段中,例如

"_id" : ObjectId("58f9d06cf998d9baccf8024f"),
"user" : ObjectId("58eda68601dc391e27f3e2c4"),
"preferences":{
 "newQuestionPrompt": false,
 "oldQuestion": false
 }

但是,当再次对同一用户进行相同的帖子调用时,调用中可能存在完全不同的属性,或者具有不同值的相同属性,例如

{
  "newQuestionPrompt": true,
  "randomQuestion": false
}

在这种情况下,我需要更新已经存在的属性的值并添加那些不属于的属性,因此早期的对象应该成为

"_id" : ObjectId("58f9d06cf998d9baccf8024f"),
"user" : ObjectId("58eda68601dc391e27f3e2c4"),
"preferences":{
"newQuestionPrompt": true,
"oldQuestion": false,
"randomQuestion": false
}

我无法使用$ set首选项:req.body,因为它会覆盖整个事物。什么是实现这一目标的最佳方式?

1 个答案:

答案 0 :(得分:0)

尝试将来电对象转换为具有dot notation键的对象,以便您可以使用 $set 更新,即转换

{
    'newQuestionPrompt': true,
    'randomQuestion': false
}

{
    'preference.newQuestionPrompt': true,
    'preference.randomQuestion': false
}

转换后,您可以在更新中将其用作:

UserPreference.findByIdAndUpdate(req.params.id, 
    {
        '$set': {
            'preference.newQuestionPrompt': true,
            'preference.randomQuestion': false
        }
    }, 
    { 'new': true },
    (err, pref) => {
        if (err) throw err;
        console.log(pref);
    }
)

要转换对象,您可以尝试以下方法:

let update = { '$set': {} };
let options = { 'new': true };
let cb = (err, pref) => {
    if (err) throw err;
    console.log(pref);
};

Object.keys(req.body).forEach((key) => {
    update['$set'][`preference.${key}`] = req.body[key];  
});

UserPreference.findByIdAndUpdate(req.params.id, update, options, cb);