(MongoDB) Добавление нового поля в документ со значением как сумма его вложенного массива вложенных документов - PullRequest
2 голосов
/ 10 июля 2020

У меня есть следующий документ коллекции пользователей:

user: {
  _id: ObjectId("...")
  name: "Kid",
  items: [
    {
       name: "pencil",
       type: "SCHOOL",
       amount: 1.00
    },
    {
       name: "computer",
       type: "PERSONAL",
       amount: 9999.99
    },
    {
       name: "notebook",
       type: "SCHOOL",
       amount: 9.00
    }
  ]
}

Теперь я пытаюсь добавить новое поле с именем schoolAmount в документ верхнего уровня, суммируя сумму во вложенном документе, равную SCHOOL тип. Таким образом, в приведенном выше примере документ будет иметь schoolAmount: 10.00 // (1 + 9). Как я мог задать такой вопрос? Мне известен только простой запрос, как показано ниже, с использованием оболочки.

db.user.updateMany({}, {$set: {"schoolAmount": <I need help here>}});

1 Ответ

1 голос
/ 10 июля 2020

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

var output = db.test.aggregate([{"$match":{name:"Kid"}},{"$unwind":"$items"},{"$match":{"items.type":"SCHOOL"}},{"$group":{"_id":"$name","total" :{$sum: "$items.amount"}}}])

while (output.hasNext()) {
   var doc = output.next();
   print(doc._id);
   print(doc.total);
   db.test.update({"name":doc._id},{$set:{"total":doc.total}})
}

Final do c

{
    "_id" : ObjectId("5f07e1616fddd269188c731c"),
    "name" : "Kid",
    "items" : [
        {
            "name" : "pencil",
            "type" : "SCHOOL",
            "amount" : 1
        },
        {
            "name" : "computer",
            "type" : "PERSONAL",
            "amount" : 9999.99
        },
        {
            "name" : "notebook",
            "type" : "SCHOOL",
            "amount" : 9
        }
    ],
    "total" : 10
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...