2016-09-09 209 views
1

我有我的mogoose架构一些嵌套的属性是这样的:猫鼬更新嵌套值

const userSchemaValues = { 
 
    username: { 
 
     type: String, 
 
     required: [true, 'Username required'], 
 
     trim: true, 
 
     unique: true, 
 
     lowercase: true 
 
    }, 
 
    password: { 
 
     type: String, 
 
     required: [true, 'Password required'], 
 
     trim: true, 
 
     minlength: 8 
 
    }, 
 
    
 
... 
 
    
 
    prop: { 
 
     prop_1: String, 
 
     prop_2: String 
 
    } 
 
};

valuesToUpdate.prop = _.pick(req.body, 'prop_1', 'prop_2'); 
 
\t log.debug(JSON.stringify(valuesToUpdate)); 
 

 
\t User.update({_id: req.params.id}, {$set: valuesToUpdate}) 
 
\t \t .then((data) => { 
 
\t \t \t return res.json({message: data}); 
 
\t \t }) 
 
\t \t .catch(err => { 
 
\t \t \t log.error(err); 
 
\t \t \t return next({message: 'Error updating User.'}); 
 
\t \t });

但是,当我在与用户做User.update({_id: req.params.id}, {$set: valuesToUpdate}) prop_1和_2用这样的对象设置({"prop":{"prop_1": "somevalue"}),它不是l为了支持什么,它只是覆盖它。我怎样才能绕过这个?

+1

你能在这里写完整的查询吗? – abdulbarik

+0

我更新了我的问题。 –

回答

2

您发现需要包括要更新的属性。另外,更新语句需要它的Positional Update Operator更改为(离开我的头):

valuesToUpdate.prop = _.pick(req.body, 'prop_1', 'prop_2'); 
    log.debug(JSON.stringify(valuesToUpdate)); 

    User.update({$and : [{_id: req.params.id}, {prop.prop1 : "%oldvalue%"}]}, {$set: { "prop.$.prop1" : "%newvalue""}}) 
     .then((data) => { 
      return res.json({message: data}); 
     }) 
     .catch(err => { 
      log.error(err); 
      return next({message: 'Error updating User.'}); 
     }); 

注意,位置更新仅更新第一次出现!

更新:重读你的问题后,我看到道具不是一个数组......我很抱歉。 幸运的是这使得它更容易:)

您不需要领域存在于找到 为集:{$设置:{“prop.prop1”:“NEWVALUE”} 同样的位置更新不是必需的,因为它不是一个数组。

这使得继:

valuesToUpdate.prop = _.pick(req.body, 'prop_1', 'prop_2'); 
log.debug(JSON.stringify(valuesToUpdate)); 

User.update({_id: req.params.id}, {$set: { "prop.prop1" : "%newvalue%"}}) 
    .then((data) => { 
     return res.json({message: data}); 
    }) 
    .catch(err => { 
     log.error(err); 
     return next({message: 'Error updating User.'}); 
    }); 

UPDATE2:有关更新语句的更多信息。

由于评论的我会澄清更新命令。 如果要更新文档中的字段,请使用$set命令。 这会更新一个或多个字段。 当你想更新多个领域,你都可以用类似的命令做到这一点:

$set : { "prop.prop1" : "newvalueforprop1", "prop.prop2" : "newvalueforprop2"} } 

但是当你使用上面的命令,并指定一个一个领域中,产生如下命令:

$set : { "prop.prop1" : "newvalueforprop1", "prop.prop2" : null} } 

这是关于如何创建更新命令的。当你不知道它是1还是2属性时,你需要更新你的代码,以便动态生成一个命令。 但你可以做的另一件事是让猫鼬处理更新。

使用类似:

User.findById(req.params.id, function (err, user) { 
     if (err) { 
      handleError(err) 
     } 
     else { 
      //you should to some checking if the supplied value is present (!= undefined) and if it differs from the currently stored one 
      user.prop.prop1 = "your value"; 
      user.prop.prop1 = "2nd value" 

      user.save(function (err) { 
       if (err) { 
        handleError(err) 
       } 
       else { 
        res.json(user); 
       } 
      }); 
     } 
    }); 

希望它现在清楚了。

+0

对于我获得的每个价值,我应该这样做{prop。$。prop_1:“%oldvalue%”}吗? 我问,因为这是一个补丁路线,我不知道哪些值将被发送更新。 –

+0

对不起,我正在更新我的答案;-),我把它放在我的头上 – HoefMeistert

+0

对不起,我不熟悉这种查询语法。但是我的IDE抱怨{$ set:{“prop。$“:”%newvalue“}}。对于prop。它期望得到一个”:“,并在$之后期望得到一个”;“? –