Как обновить значение массива в mongodb с помощью агрегации
Мой документ выглядит примерно так
{ _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 }
Я пытаюсь обновить процентCompleted и один из списка процессов isCompleted true на основе идентификатора внутри processList.
Я выполнил этот запрос, но выдает ошибку
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), вычисляется и устанавливается обновление процентного завершения. Может кто-нибудь помочь мне, как действовать. Заранее спасибо.
2 ответа
Мы можем смешивать операторы обновления с агрегатными операторами, если нам нужны агрегатные операторы, мы обновляем их с помощью конвейерного обновления.
обновления конвейера требуют MongoDB>=4.2
Запрос
- карта для обновления списка процессов
- ваш
$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
]
}
}
}
])
Невозможно. Агрегация используется только для выборки / чтения данных.
Вы должны работать с 2 запросами с сервера.
Сначала найти значение для обновления с помощью агрегата.
Затем сделайте еще один запрос на обновление значения.
Этот метод не сработает, если вы ожидаете одновременного запроса нескольких запросов на обновление одного и того же документа.