order
、
vendorID
,而该输入参数已经存在于特定的
orderNumber
中,我需要在
orders
数组中更新它,方法是将整个现有订单元素替换为
orderNumber
。输入参数中新提供的顺序,否则插入它假设输入参数具有三个属性:
orderNumber : "order2"
order: {"orderNumber":"order2", "data":"NEW_DATA_FROM_INPUT" }
vendorId : "vendor1"
{
"_id":1,
"vendorId":"Vendor1",
"orders":[
{
"orderNumber":"order1",
"data":"data1"
},
{
"orderNumber":"order2",
"data":"data2"
}
]
}
查询应更新记录如下:
{
"_id":1,
"vendorId":"Vendor1",
"orders":[
{
"orderNumber":"order1",
"data":"data1"
},
{
"orderNumber":"order2",
"data":"NEW_DATA_FROM_INPUT" // !!
}
]
}
尝试过$set
、
$addtoSet
,但由于 mongo 限制,它们不能在同一路径上一起使用。
聚合管道。
注意:下面列出的update
中的评论。根据您使用的应用程序/驱动程序,您可能需要将
db.collection.update
更改为其他内容(并且您可能不想要/不需要
{"multi": true}
)。
db.collection.update({
// find doc with correct "vendorId"
"vendorId": "Vendor1"
},
// use pipeline
[{
// rebuild "orders"
"$set": {
"orders": {
"$let": {
"vars": {
// from input params
"orderParam": {
"orderNumber": "order2",
"data": "NEW_DATA_FROM_INPUT"
}
},
"in": {
"$cond": [
// does "orders.orderNumber" exist and is array?
{
"$eq": [{"$type": "$orders.orderNumber"}, "array"]
},
// yes, "orders.orderNumber" exists and is array
{
"$cond": [
// does an order need rewriten "data"?
{
"$in": ["order2", "$orders.orderNumber"]
},
// yes, rewrite specific order, keep the rest
{
"$map": {
"input": "$orders",
"as": "order",
"in": {
"$cond": [
// is this the order?
{
"$eq": ["$$order.orderNumber", "$$orderParam.orderNumber"]
},
// yes, rewrite this order
{
"$mergeObjects": [
"$$order",
{"data": "$$orderParam.data"}
]
},
// not the order, so keep it
"$$order"
]
}
}
},
// no, order is not there, so just append it
{
"$concatArrays": ["$orders", ["$$orderParam"]]
}
]
},
// nobody home, create it
["$$orderParam"]
]
}
}
}
}
}
],
{
"multi": true
})
在 mongoplayground.net 上尝试一下,你会看到各种测试用例。