【问题标题】:Update all objects in array and inner array that match更新数组和内部数组中匹配的所有对象
【发布时间】:2020-08-29 11:52:35
【问题描述】:

我有这个文档结构

{
    "_id": <OBJECT_ID>,
    "orders": [
         {
              "userId": 1,
              "handleName": "John Doe",
              "orderAmount": 3,
              "others": [
                   {
                        "userId": 1,
                        "handleName": "John Doe"
                   },
                   {
                        "userId": 2,
                        "handleName": "Maria Gigante"
                   }
              ]
         },
         {
              "userId": 2,
              "handleName": "Maria Gigante",
              "orderAmount": 2,
              "others": [
                   {
                        "userId": 1,
                        "handleName": "John Doe"
                   },
                   {
                        "userId": 2,
                        "handleName": "Maria Gigante"
                   }
              ]
         },
         {
              "userId": 1,
              "handleName": "John Doe",
              "orderAmount": 4,
              "others": [
                   {
                        "userId": 1,
                        "handleName": "John Doe"
                   },
                   {
                        "userId": 2,
                        "handleName": "Maria Gigante"
                   }
              ]
         },
         {
              "userId": 3,
              "handleName": "John Doe",
              "orderAmount": 4,
              "others": [
                   {
                        "userId": 1,
                        "handleName": "John Doe"
                   },
                   {
                        "userId": 2,
                        "handleName": "Maria Gigante"
                   }
              ]
         }
    ]
}

我想更新具有1userIdJohn DoehandleName 的所有对象。 请注意,对象可以具有相同的句柄名称但不同的用户 ID。这就是为什么我需要先将它与userId 匹配。

比如我想把句柄名改成Donald Stark

我想要这个结果:

{
    "_id": <OBJECT_ID>,
    "orders": [
         {
              "userId": 1,
              "handleName": "Donald Stark",
              "orderAmount": 3,
              "others": [
                   {
                        "userId": 1,
                        "handleName": "Donald Stark"
                   },
                   {
                        "userId": 2,
                        "handleName": "Maria Gigante"
                   }
              ]
         },
         {
              "userId": 2,
              "handleName": "Maria Gigante",
              "orderAmount": 2,
              "others": [
                   {
                        "userId": 1,
                        "handleName": "Donald Stark"
                   },
                   {
                        "userId": 2,
                        "handleName": "Maria Gigante"
                   }
              ]
         },
         {
              "userId": 1,
              "handleName": "Donald Stark",
              "orderAmount": 4,
              "others": [
                   {
                        "userId": 1,
                        "handleName": "Donald Stark"
                   },
                   {
                        "userId": 2,
                        "handleName": "Maria Gigante"
                   }
              ]
         },
         {
              "userId": 3,
              "handleName": "John Doe",
              "orderAmount": 4,
              "others": [
                   {
                        "userId": 1,
                        "handleName": "Donald Stark"
                   },
                   {
                        "userId": 2,
                        "handleName": "Maria Gigante"
                   }
              ]
         }
    ]
}

这是如何实现的?

更新: 我忘了我还有另一个内部数组也想更新。

【问题讨论】:

  • 请用您尝试过的代码更新您的问题。
  • 这能回答你的问题吗? arrayFilters in mongodb
  • @whoami 抱歉,我忘记了我还有一个要更新的内部数组。我已经更新了我的问题,请再看一遍。

标签: python mongodb mongodb-query pymongo aws-documentdb


【解决方案1】:

我们可以使用$[identifier] 操作符来更新数组中的特定对象

所以你的更新查询应该看起来像

db.collection.updateOne(
    { _id: <OBJECT_ID> }, // filter part, add the real objectId here
    { $set: { 'orders.$[order].handleName': 'Donald Stark' } }, // update part
    { arrayFilters: [{ 'order.userId': 1, 'order.handleName': 'John Doe' }] 
})

$[order] 只更新符合数组过滤条件的对象


更新

如果你有一个内部数组,并且你需要对该内部数组中的元素做同样的事情,我们可以使用类似的东西

db.collection.updateOne(
    { _id: <OBJECT_ID> }, // filter part, add the real objectId here
    { $set: { 
        'orders.$[order].handleName': 'Donald Stark', // to set the handleName in the elements of the outer array
        'orders.$[].others.$[other].handleName': 'Donald Stark' // to set the handleName in the elements of the inner array
    } },
    { arrayFilters: [{ 'order.userId': 1, 'order.handleName': 'John Doe' }, { 'other.userId': 1, 'other.handleName': 'John Doe' }] }
)

我们使用$[]循环遍历orders数组中的所有元素,然后使用$[other]根据数组filters中的新条件更新内部数组中的特定元素

希望对你有帮助

【讨论】:

  • 确实这将是正确的答案,但我已经更新了我的问题。我还有一个内部数组,其中包含我也想更新的类似数据。
  • 好的,我已经更新了我的答案来处理这个问题,你能检查一下吗?
【解决方案2】:

这样的东西能解决你的问题吗?

d = {
    "_id": <OBJECT_ID>,
    "orders": [
         {
              "userId": 1,
              "handleName": "John Doe",
              "orderAmount": 3
         },
         {
              "userId": 2,
              "handleName": "Maria Gigante",
              "orderAmount": 2
         },
         {
              "userId": 1,
              "handleName": "John Doe",
              "orderAmount": 4
         },
         {
              "userId": 3,
              "handleName": "John Doe",
              "orderAmount": 4
         }
    ]
}

def change_name(usr_id, old_name, new_name):
    for usr in d['orders']:
        if usr['userId'] == usr_id and usr['handleName'] == old_name:
            usr['handleName'] = new_name

change_name(1, 'John Doe', 'Donald Stark')

【讨论】:

  • 抱歉,数据在文档数据库集合中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-25
  • 1970-01-01
  • 2017-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多