Mongoose - 增加对象数组内的值

Ale*_*dro 1 javascript mongoose mongodb node.js

我很难弄清楚如何增加数组中对象的值

例如,我有一个基于Poll模式的文档:

{
  "_id": "584b2cc6817758118e9557d8",
  "title": "Number of Skittles",
  "description": "Test1",
  "date": "Dec 9, 2016",
  "__v": 0,
  "labelOptions": [
    {
      "Bob": 112
    },
    {
      "Billy": 32
    },
    {
      "Joe": 45
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

使用express,我能够做到这一点:

app.put('/polls/:id', function(req, res){
  let id = req.params.id;
  let labelOption = req.query.labelOption;
  Poll.findOneAndUpdate(
    {'_id' :  id},
    {$inc: {`labelOptions.$.${labelOption}`: 1 }},
    function(err){
      console.log(err)
    })
Run Code Online (Sandbox Code Playgroud)

labelOption我想增加其价值的那个在哪里

更简洁地说,我在遍历文档内部时遇到问题。

bor*_*mke 5

.find如果labelOptions是对象数组,则无法直接增加查询中的值。为了使它更容易,您应该将labelOptions类​​型从对象数组更改为对象:

"labelOptions": {
    "Bob": 112,
    "Billy": 32,
    "Joe": 45
};
Run Code Online (Sandbox Code Playgroud)

.findByIdAndUpdate如果您通过.findOneAndUpdate文档的_id. 然后,您可以通过以下方式实现您想要的:

Poll.findByIdAndUpdate(
    id,
    {$inc: {`labelOptions.${labelOption}`: 1 }},
    function(err, document) {
    console.log(err);
});
Run Code Online (Sandbox Code Playgroud)

更新:如果您坚持使用对象数组 for labelOptions,有一个解决方法:

Poll.findById(
    id,
    function (err, _poll) {

        /** Temporarily store labelOptions in a new variable because we cannot directly modify the document */
        let _updatedLabelOptions = _poll.labelOptions;

        /** We need to iterate over the labelOptions array to check where Bob is */
        _updatedLabelOptions.forEach(function (_label) {

            /** Iterate over key,value of the current object */
           for (let _name in _label) {

               /** Make sure that the object really has a property _name */
               if (_label.hasOwnProperty(_name)) {

                   /** If name matches the person we want to increment, update it's value */
                   if (_name === labelOption) ++_label._name;
               }
           }
        });

        /** Update the documents labelOptions property with the temporary one we've created */
        _poll.update({labelOptions: _updatedLabelOptions}, function (err) {

            console.log(err);
        });
    });
Run Code Online (Sandbox Code Playgroud)


wcj*_*ord 5

还有另一种方法可以实现更灵活的文档模型。如果您向对象添加一个字段,例如:

{
  "_id": "584b2cc6817758118e9557d8",
  "title": "Number of Skittles",
  "description": "Test1",
  "date": "Dec 9, 2016",
  "__v": 0,
  "labelOptions": [
    {
      "name": "Bob",
      "number": 112
    },
    {
      "name": "Billy",
      "number": 32
    },
    {
      "name": "Joe"
      "number": 45
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

app.put('/polls/:id', function(req, res){
  let id = req.params.id;
  let labelOption = req.query.labelOption;
  Poll.findOneAndUpdate(
    {
     '_id' :  id,
     'labelOptions.name': labelOption
    },
    {$inc: {
      "labelOptions.$.number": 1 
    }},
    function(err){
      console.log(err)
    })
 });
Run Code Online (Sandbox Code Playgroud)