当我在MongoDB集合中运行getById()函数时,我想使用$aggregate
和$addFields
动态填充字段。基本上,我想做的是从称为“ history”的属性中提取对象数组中的最后一个元素,并将其动态填充到名为“ 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"
}
}
答案 0 :(得分:1)
此行:
await db.collection("staffmembers").aggregate([{ $addFields: { activeStatus: { $arrayElemAt: ["$history", -1.0] } } }, { $out: "staffmembers" }])
返回类型AggregationCursor,因为您使用的是原始的node.js MongoDB驱动程序。因此,实际上没有执行数据库调用。
您有两种方法可以解决此问题:
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()