【发布时间】:2020-02-07 05:02:07
【问题描述】:
我有一个类似这样结构的 Event 文档,我正在尝试查询 employeeResponses 数组以收集单个员工的所有响应(可能存在也可能不存在):
[
{
...
eventDate: 2019-10-08T03:30:15.000+00:00,
employeeResponses: [
{
_id:"5d978d372f263f41cc624727",
response: "Available to work.",
notes: ""
},
...etc
];
}
];
我目前的猫鼬聚合是:
const eventResponses = await Event.aggregate([
{
// find all events for a selected month
$match: {
eventDate: {
$gte: startOfMonth,
$lte: endOfMonth,
},
},
},
{
// unwind the employeeResponses array
$unwind: {
path: "$employeeResponses",
preserveNullAndEmptyArrays: true,
},
},
{
$group: {
_id: null,
responses: {
$push: {
// if a response id matches the employee's id, then
// include their response; otherwise, it's a "No response."
$cond: [
{ $eq: ["$employeeResponses._id", existingMember._id] },
"$employeeResponses.response",
"No response.",
],
},
},
},
},
{ $project: { _id: 0, responses: 1 } },
]);
您无疑会注意到,在超过 1 名员工记录回复后,上述查询将不起作用,因为它将每个单独的回复视为 T/F 条件,而不是所有回复 在 employeeResponses 数组中作为单个 T/F 条件。
因此,我删除了初始 $match 之后的所有后续查询并进行了手动减少:
const responses = eventResponses.reduce((acc, { employeeResponses }) => {
const foundResponse = employeeResponses.find(response => response._id.equals(existingMember._id));
return [...acc, foundResponse ? foundResponse.response : "No response."];
}, []);
我想知道是否有可能实现上述相同的减少结果,但也许使用 mongo 的 $reduce 函数?或者重构上面的聚合查询以将employeeResponses 中的所有响应视为单个 T/F 条件?
此聚合的最终目标是从当前月份内找到的每个 Event 中提取任何先前记录的员工的回复和/或缺少回复,并将他们的回复放入单个数组中:
["I want to work.", "Available to work.", "Not available to work.", "No response.", "No response." ...etc]
【问题讨论】:
标签: mongodb mongoose aggregation-framework