【问题标题】:Mongoose - Increment a value inside an array of objectsMongoose - 在对象数组中增加一个值
【发布时间】:2017-04-25 15:32:52
【问题描述】:

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

例如,我有这个基于 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 是我想要增加它的值的地方

为了更简洁,我无法在文档中进行横向移动。

【问题讨论】:

    标签: javascript node.js mongodb mongoose


    【解决方案1】:

    如果labelOptions 是对象数组,则无法直接增加.find 查询中的值。为方便起见,您应该将 labelOptions 类型从 Array of Objects 更改为 Object:

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

    如果您通过文档的_id 进行查询,还可以考虑使用.findByIdAndUpdate 而不是.findOneAndUpdate。然后,您可以通过以下方式实现您想要的:

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-16
        • 2013-04-02
        相关资源
        最近更新 更多