【问题标题】:MongoDB $addToSet to deep nested array of objectMongoDB $addToSet 到对象的深层嵌套数组
【发布时间】:2019-02-17 01:25:25
【问题描述】:

下面是我的数据结构。

{
    "_id" : "room1",
    "members" : [ 
        {
            "_id" : "member1",
            "name" : "Michael",
            "payments" : [
                {
                    "month": "2018/09"
                    "amount": "20"
                }
            ]
        }, 
    ]
}

我想将下面的对象推送到迈克尔的payments

{ 
  "month": "2018/09", 
  "amount": "5000" 
}

在这种情况下,我想要的是覆盖对象,因为month: "2018/09" 已经存在。如下:

{
    "_id" : "room1",
    "members" : [ 
        {
            "_id" : "member1",
            "name" : "Michale",
            "payments" : [
                {
                    "month": "2018/09"
                    "amount": "5000"
                }
            ]
        }, 
    ]
}

而且,如果我想在付款中推送不存在相同month 的对象,我想将此对象添加到payments

{ 
  "month": "2018/10", 
  "amount": "2000" 
}

所以预期的结果是

{
    "_id" : "room1",
    "members" : [ 
        {
            "_id" : "member1",
            "payments" : [
                {
                    "month": "2018/09"
                    "amount": "5000"
                },
                {
                    "month": "2018/10"
                    "amount": "2000"
                }
            ]
        }, 
    ]
}

我尝试了下面的方法,但它不起作用。每次我尝试时,我的代码都会生成重复的新 month 对象。我怎样才能正确地做到这一点?

Rooms.update(
    {
        _id: "room1",
        "members._id": "member1",
        "members.$.payments": {
            $not: {
                $elemMatch: {
                    month: req.body.month
                }
            }
        }
    },
    {
        $addToSet: {
            "members.$.payments": {
                month: req.body.month,
                amount: req.body.value
            }
        }
    },
    { multi: true }, function (err, result) {
        console.log(result)
    }
)

【问题讨论】:

  • 在这里使用$ne 而不是$not..."members.$.payments": { $elemMatch: { month: { $ne: req.body.month } } }
  • 在查询部分去掉members.$.payments中的$。
  • @AnthonyWinzlet 我加了你们的建议,但仍然没有工作......它不再生成重复的对象,但它没有被覆盖。
  • @Veeram 谢谢,我删除了它。但它仍然无法正常工作——不再有重复的对象,但没有被覆盖
  • 按预期工作。 $addToSet 不会覆盖元素。

标签: node.js mongodb mongoose mongodb-query


【解决方案1】:

也许考虑将嵌套数组的结构更改为对象?所以改变这个

{
  "payments": [{
      "month": "2018/09"
      "amount": "5000"
    },
    {
      "month": "2018/10"
      "amount": "2000"
    }
  ]
}

到这里:

{
  "payments": {
    "2018/09": "5000",
    "2018/10": "2000"
  }
}

然后你可以做一个简单的更新:

Rooms.update({
    _id: "room1",
    "members._id": "member1",
    "members.payments": {
      $exists: true
    }
  }, {
    $set: {
      "members.payments." + req.body.month: req.body.value
    }
  },

)

【讨论】:

    【解决方案2】:

    所以我听说我必须自己确定重复,所以下面是我的代码...现在正在编写。,,


    所以最后这是我的代码

      Clubs.findOne({ 
            uid: req.params.club_id,
            "members._id": mongoose.Types.ObjectId(req.params.member_uid)
        }, function(err, club){
    
            let member = club.members.filter(el => {
                if(el._id.equals(req.params.member_uid)) return el
            })
    
            let duplicated = false; 
            member[0].payments.map(el => {
                if(el.month === req.body.month) duplicated = true
            })
    
           if(duplicated){
    
            Clubs.update(
                {
                    uid: req.params.club_id,
                    "members._id": mongoose.Types.ObjectId(req.params.member_uid),
                },
                {
                    $set: {
                        ["members.$.payments."+index+".amount"] : req.body.value
                    }
                },
                function (err, result, third) {
                    if (err) throw err
                    console.log('result')
                    console.log(result)
                    res.json({})
                }
            )
    
    
        } else {
    
            Clubs.update(
                {
                    uid: req.params.club_id,
                    "members._id": mongoose.Types.ObjectId(req.params.member_uid),
                },
                {
                    $push: {
                        "members.$.payments" : { 
                            month : req.body.month, 
                            amount: req.body.value 
                        }
                    }
                },
                function (err, result, third) {
                    if (err) throw err
                    console.log('result')
                    console.log(result)
                    res.json({})
                }
            )
        }
    
        })
    

    【讨论】:

      【解决方案3】:

      您可以使用以下命令在月份或金额中添加不重复的内容

      Rooms.update(
          {
              _id: "room1",
              "members._id": "member1"
          },
          {
              $addToSet: {
                  "members.$.payments": {
                      month: req.body.month,
                      amount: req.body.value
                  }
              }
          },function (err, result) {
              console.log(result)
          }
      )
      

      【讨论】:

      • 你红了我的问题吗...你的回答会产生重复的对象。
      • 不,不是我在本地检查过的
      • 这和 Juntae 在他原来的帖子里写的一样。这会导致错误“位置运算符未从查询中找到所需的匹配项”。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-15
      • 2019-01-13
      • 1970-01-01
      • 1970-01-01
      • 2020-04-13
      • 2018-05-21
      相关资源
      最近更新 更多