Перемещение элемента из одного массива в другой с использованием одного и того же запроса Mongo updateOne

#mongodb

Вопрос:

У меня есть следующая модель данных:

 "finances" : {
    "futurePostings" : [ 
        {
            "description" : "test",
            "orderId" : ObjectId("614702b9e98e83bc5d7d3d62")
        }
    ],
    "balance" : []
}
 

Затем я пытаюсь переместить элемент внутрь futurePosting balance . Я мог бы удалить его из будущих сообщений, но я не могу понять, можно ли было бы использовать позиционный оператор $ (или любую другую команду), чтобы вставить этот же документ в баланс с помощью того же запроса.

    db.collection.updateOne(
        {
          "finances.futurePostings.orderId": ObjectId(orderId),
        },
        {
          $push: { "finances.balance": ?? },
          $pull: {
            "finances.futurePostings": { orderId: ObjectId(orderId) },
          },
        }
      );
 

Возможно ли это?

Ответ №1:

Это невозможно в обычном запросе на обновление, но вы можете попробовать обновить с помощью конвейера агрегации, начиная с MongoDB 4.2,

  • вытащить из futurePostings
    • $filter для повторения цикла futurePostings массива и проверки не равно условию для удаления при условии orderId
  • протолкнуться в balance
    • $filter для повторения цикла futurePostings массива и проверки соответствия условию и фильтрующему orderId элементу
    • $concatArrays для объединения текущего balance массива и нового элемента из отфильтрованного результата выше
 db.collection.updateOne(
  { "finances.futurePostings.orderId": ObjectId(orderId) },
  [{
    $set: {
      "finances.futurePostings": {
        $filter: {
          input: "$finances.futurePostings",
          cond: {
            $ne: ["$this.orderId", ObjectId(orderId)]
          }
        }
      },
      "finances.balance": {
        $concatArrays: [
          "$finances.balance",
          {
            $filter: {
              input: "$finances.futurePostings",
              cond: {
                $eq: ["$this.orderId", ObjectId(orderId)]
              }
            }
          }
        ]
      }
    }
  }]
)
 

Игровая площадка