如何使用聚合更新 mongodb 中的数组值
How to update an array value in mongodb using aggregation
我的文档看起来像这样
{ _id: ObjectId("60b114b2415731001943b17f"),
processList:[
{ processName: 'Wood cutting',
createdAt: '2021-05-28T08:59:06.260Z',
updatedAt: '2021-05-28T08:59:06.260Z',
id: '60b0f0e9659a3b001c235300',
endTime: '2021-07-09T22:25:57.973Z',
isCompleted: false },
{ processName: 'Painting',
createdAt: '2021-05-28T13:32:02.441Z',
updatedAt: '2021-05-28T13:32:02.441Z',
id: '60b0f0e9659a3b001c235301',
endTime: 2021-05-28T17:05:06.067Z,
isCompleted: true },
{processName: 'Varnishing',
createdAt: '2021-05-28T09:46:33.169Z',
updatedAt: '2021-05-28T09:46:33.169Z',
id: '60b0f0e9659a3b001c235302',
endTime: 2021-05-28T20:05:06.067Z,
isCompleted: false }
],
companyId: '60b0a2b7b0beab001a068f8c',
customerId: '60b11289415731001943b17d',
productName: 'Queen size bed',
quantity: 1,
orderStartedTime: 2021-05-28T16:05:06.067Z,
estimatedEndTime: 2021-05-29T01:05:06.067Z,
createdAt: 2021-05-28T16:05:06.069Z,
updatedAt: 2021-07-09T22:20:58.019Z,
__v: 0,
percentageCompleted: 33.33333333333333 }
我正在尝试根据 processList 中的 id 更新 percentageCompleted 和进程列表之一的 isCompleted true。
我运行这个查询但是抛出错误
db.orders.findOneAndUpdate(
{
_id: ObjectId('60b114b2415731001943b17f')
},
[
{
$set: {"processList.$[element].isCompleted": true}
},
{
multi: true,
arrayFilters: [{ 'element.id': { $eq: "60b0f0e9659a3b001c235300" } }],
},
{
$set: {
percentageCompleted: {
$multiply: [
{
$divide: [{
$size: {
$filter: {
input: "$processList",
as: "process",
cond: { $eq: ["$$process.isCompleted", true] }
}
}
},
{ $size: "$processList" }]
}, 100
]
},
}
}
]
)
当我排除数组更新(isCompleted)时,percentageCompleted 的更新正在计算和设置。有人可以帮助我如何进行。提前致谢。
不可能。聚合仅用于 fetch/read 数据。
您必须处理来自服务器的 2 个查询。
首先使用聚合找到要更新的值。
然后再次请求更新值。
如果您希望同时有多个请求尝试更新同一文档,则此方法无效。
我们可以将更新运算符与聚合运算符混合使用,如果我们需要聚合运算符,我们会使用管道更新来更新它。
pipeline updates require MongoDB >=4.2
查询
- map更新processList
- 您的
$set
来自您的查询
db.collection.update({
"_id": "60b114b2415731001943b17f"
},
[
{
"$set": {
"processList": {
"$map": {
"input": "$processList",
"in": {
"$cond": [
{
"$eq": [
"$$this.id",
"60b0f0e9659a3b001c235300"
]
},
{
"$mergeObjects": [
"$$this",
{
"isCompleted": true
}
]
},
"$$this"
]
}
}
}
}
},
{
"$set": {
"percentageCompleted": {
"$multiply": [
{
"$divide": [
{
"$size": {
"$filter": {
"input": "$processList",
"as": "process",
"cond": {
"$eq": [
"$$process.isCompleted",
true
]
}
}
}
},
{
"$size": "$processList"
}
]
},
100
]
}
}
}
])
我的文档看起来像这样
{ _id: ObjectId("60b114b2415731001943b17f"),
processList:[
{ processName: 'Wood cutting',
createdAt: '2021-05-28T08:59:06.260Z',
updatedAt: '2021-05-28T08:59:06.260Z',
id: '60b0f0e9659a3b001c235300',
endTime: '2021-07-09T22:25:57.973Z',
isCompleted: false },
{ processName: 'Painting',
createdAt: '2021-05-28T13:32:02.441Z',
updatedAt: '2021-05-28T13:32:02.441Z',
id: '60b0f0e9659a3b001c235301',
endTime: 2021-05-28T17:05:06.067Z,
isCompleted: true },
{processName: 'Varnishing',
createdAt: '2021-05-28T09:46:33.169Z',
updatedAt: '2021-05-28T09:46:33.169Z',
id: '60b0f0e9659a3b001c235302',
endTime: 2021-05-28T20:05:06.067Z,
isCompleted: false }
],
companyId: '60b0a2b7b0beab001a068f8c',
customerId: '60b11289415731001943b17d',
productName: 'Queen size bed',
quantity: 1,
orderStartedTime: 2021-05-28T16:05:06.067Z,
estimatedEndTime: 2021-05-29T01:05:06.067Z,
createdAt: 2021-05-28T16:05:06.069Z,
updatedAt: 2021-07-09T22:20:58.019Z,
__v: 0,
percentageCompleted: 33.33333333333333 }
我正在尝试根据 processList 中的 id 更新 percentageCompleted 和进程列表之一的 isCompleted true。
我运行这个查询但是抛出错误
db.orders.findOneAndUpdate(
{
_id: ObjectId('60b114b2415731001943b17f')
},
[
{
$set: {"processList.$[element].isCompleted": true}
},
{
multi: true,
arrayFilters: [{ 'element.id': { $eq: "60b0f0e9659a3b001c235300" } }],
},
{
$set: {
percentageCompleted: {
$multiply: [
{
$divide: [{
$size: {
$filter: {
input: "$processList",
as: "process",
cond: { $eq: ["$$process.isCompleted", true] }
}
}
},
{ $size: "$processList" }]
}, 100
]
},
}
}
]
)
当我排除数组更新(isCompleted)时,percentageCompleted 的更新正在计算和设置。有人可以帮助我如何进行。提前致谢。
不可能。聚合仅用于 fetch/read 数据。
您必须处理来自服务器的 2 个查询。
首先使用聚合找到要更新的值。
然后再次请求更新值。
如果您希望同时有多个请求尝试更新同一文档,则此方法无效。
我们可以将更新运算符与聚合运算符混合使用,如果我们需要聚合运算符,我们会使用管道更新来更新它。
pipeline updates require MongoDB >=4.2
查询
- map更新processList
- 您的
$set
来自您的查询
db.collection.update({
"_id": "60b114b2415731001943b17f"
},
[
{
"$set": {
"processList": {
"$map": {
"input": "$processList",
"in": {
"$cond": [
{
"$eq": [
"$$this.id",
"60b0f0e9659a3b001c235300"
]
},
{
"$mergeObjects": [
"$$this",
{
"isCompleted": true
}
]
},
"$$this"
]
}
}
}
}
},
{
"$set": {
"percentageCompleted": {
"$multiply": [
{
"$divide": [
{
"$size": {
"$filter": {
"input": "$processList",
"as": "process",
"cond": {
"$eq": [
"$$process.isCompleted",
true
]
}
}
}
},
{
"$size": "$processList"
}
]
},
100
]
}
}
}
])