Динамическое заполнение поля с помощью $ addfields при получении документа по идентификатору

Я хотел бы использовать $aggregate и $addFields для динамического заполнения поля при запуске функции getById () в моей коллекции MongoDB. По сути, я хочу извлечь последний элемент в массиве объектов из свойства, называемого «история», и динамически заполнить его в поле с именем «activeStatus», которое является объектом. Итак, этот конкретный блок кода выглядит так:

await db.collection("staffmembers").aggregate([{ $addFields: { activeStatus: { $arrayElemAt: ["$history", -1.0] } } }, { $out: "staffmembers" }]);

Вот как выглядит полная функция getById ():

exports.getById = async function(req, res) {
  let doc;
  let MongoClient = await require("../config/database")();
  let db = MongoClient.connection.db;

  let request = new EndpointRequestController(
    req,
    res,
    // Allowed Parameters
    {
      id: {
        type: String
      }
    },
    [
      // Required Parameters
      "id"
    ]
  );

  await db.collection("staffmembers").aggregate([{ $addFields: { activeStatus: { $arrayElemAt: ["$history", -1.0] } } }, { $out: "staffmembers" }]);

  try {
    doc = await StaffMember.findOne(
      {
        _id: request.parameters.id
      },
      {}
    ).exec();
    if (doc) req.documentCount = 1;
  } catch (err) {
    return request.sendError("An error occurred while trying to find existing records.", err);
  }

  res.send(doc);
};

Хотя я не получаю никаких ошибок, я не вижу «activeStatus» в итоговом документе.

Могу ли я сделать это в такой ситуации? И если да, то чего мне не хватает?

Кстати, мой документ выглядит так:

{
    "_id": <id value>,
    "type": "permanent",
    "gender": "female",
    "history": [
        {
            "endDate": "2018-10-31T12:27:17.721Z",
            "stage": "training",
            "completed": true,
            "startDate": "2018-10-30T13:41:18.714Z"
        },
        {
            "stage": "active",
            "completed": false,
            "startDate": "2018-10-31T12:27:17.572Z"
        }
    ]
}

И это документ, который я хочу создать:

{
    "_id": <id value>,
    "type": "permanent",
    "gender": "female",
    "history": [
        {
            "endDate": "2018-10-31T12:27:17.721Z",
            "stage": "training",
            "completed": true,
            "startDate": "2018-10-30T13:41:18.714Z"
        },
        {
            "stage": "employed",
            "completed": false,
            "startDate": "2018-10-31T12:27:17.572Z"
        }
    ],
    "activeStatus": {
            "stage": "employed",
            "completed": false,
            "startDate": "2018-10-31T12:27:17.572Z"
    }
}

Я предполагаю, что ожидание отсутствует перед aggregate, не могли бы вы попробовать?

mickl 31.10.2018 13:51

Я добавил «ожидание» перед агрегатным блоком, но все равно ничего.

Muirik 31.10.2018 13:54
0
2
367
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Эта строка:

await db.collection("staffmembers").aggregate([{ $addFields: { activeStatus: { $arrayElemAt: ["$history", -1.0] } } }, { $out: "staffmembers" }])

возвращает тип АгрегацияКурсор, поскольку вы используете необработанный драйвер MongoDB node.js. Так что на самом деле вызов базы данных не выполняется.

У вас есть два способа исправить это:

1) Используйте API мангуста:

await StaffMember.aggregate([{ $addFields: { activeStatus: { $arrayElemAt: ["$history", -1.0] } } }, { $out: "staffmembers" }]);

2) "Заставить" курсор выполнить запрос (используя next() или toArray())

let cursor = db.collection('staffmembers').aggregate([{ $addFields: { activeStatus: { $arrayElemAt: ["$history", -1.0] } } }, { $out: "staffmembers" }]);
await cursor.toArray()

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