Как обновить значение массива в 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 запросами с сервера.

Сначала найти значение для обновления с помощью агрегата.

Затем сделайте еще один запрос на обновление значения.

Этот метод не сработает, если вы ожидаете одновременного запроса нескольких запросов на обновление одного и того же документа.

Другие вопросы по тегам