Mongoose - 增加对象数组中的值

时间:2016-12-10 05:36:59

标签: javascript node.js mongodb mongoose

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

例如,我的文档基于Poll架构:

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

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

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)
    })

其中labelOption是我想增加其值的那个

为了更简洁,我在文档中横向移动时遇到了麻烦。

2 个答案:

答案 0 :(得分:2)

如果.find是一个Object of Array,则无法直接递增labelOptions查询中的值。为了简化操作,您应该将labelOptions类型从对象数组更改为对象:

"labelOptions": {
    "Bob": 112,
    "Billy": 32,
    "Joe": 45
};

如果您要查询文档.findByIdAndUpdate,请考虑使用.findOneAndUpdate代替_id。然后,您可以实现您想要的目标:

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

更新:如果您坚持使用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);
        });
    });

答案 1 :(得分:0)

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

{
  "_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
    }
  ]
}

那么您可以做:

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