1

我有这个文档结构

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

我想更新所有具有userIdof1handleNameof的对象John Doe。请注意,对象可以具有相同的句柄名称但不同的用户 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"
                   }
              ]
         }
    ]
}

这是如何实现的?

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

4

2 回答 2

3

we can use $[identifier] operator to update specific objects in the array

so your update query should look something like

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] to update only the objects that match the conditions in the array filters


Update

If you have an inner array, and you need to do the same thing for the elements inside that inner array, we could use something like that

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

we used $[] to loop over all the elements in the orders array, then use $[other] to update specific elements in the inner array according to the new condition in the array filters

hope it helps

于 2020-05-13T11:01:13.717 回答
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')
于 2020-05-13T10:28:56.593 回答