我有这样的文档结构
{
"_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"
}
]
}
]
}
我想更新所有具有以下功能的对象。userId
的 1
和 handleName
的 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"
}
]
}
]
}
如何实现?
更新:我忘了我还有一个内部数组,我也想更新。
我们可以使用 $[标识符] 操作符来更新数组中的特定对象
所以你的更新查询应该是这样的
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' }] }
)
我们用 $[]
循环处理订单数组中的所有元素,然后使用 $[other]
根据数组过滤器中的新条件更新内部数组中的特定元素。
希望对你有帮助
这样的东西能解决你的问题吗?
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')