Mongoose - 将子文档附加到与值匹配的结果

时间:2017-03-31 02:05:30

标签: node.js mongoose mongodb-query aggregation-framework

我有两个收藏集 - AssignmentsSubmissions - 教师可以在其中分配作业,所有学生都可以上传提交内容。我想查询数据库,以便我将检索已发布的所有作业,并且每个作业都会检索学生提交的作业标签(如果存在)。

AssignmentSchema = new Schema({
    teacher: {type: Schema.Types.ObjectId, ref: 'User', required: true},
    course: {type: Schema.Types.ObjectId, ref: 'Course', required: true},
    name: {type: String},
    ...
});

SubmissionSchema = new Schema({
    assignment: {type: Schema.Types.ObjectId, ref: 'Assignment', required: true},
    student: {type: Schema.Types.ObjectId, ref: 'User', required: true},
    ...
});

尝试使用聚合框架

Assignment.aggregate([
    {$match: {'course': new ObjectId(req.params.courseID)}},
    {$lookup: {
        from: 'submissions',
        localField: '_id',
        foreignField: 'assignment',
        as: 'submission'
    }},

    // Redact all submissions that aren't uploaded by the logged in user
    {$redact: {
        // This condition isn't working for some reason?
        $cond: {
            if: {
                $eq: ['$submission.user', new ObjectId(req.user._id)]
            },
            'then': '$$DESCEND',
            'else': '$$PRUNE' // Prune will remove the entire object. How can I only remove the assignments?
        }
    }},
    {$unwind: {
        path: '$submission',
        preserveNullAndEmptyArrays: true
    }}
]);

我需要的结果是:

[{
    _id: '123456789',
    teacher: {teacher's id},
    course: '987654321',
    name: 'The assignment',
    submission: {
        assignment: '123456789',
        student: {authenticated user's id},
        ...
    },
    ...
}]

1 个答案:

答案 0 :(得分:1)

将您的$eq表达式替换为

[{$ifNull: ["$user", new ObjectId(req.user._id)]}, new ObjectId(req.user._id)]

$redact一次只能获得一个文档级别,并递归查找user字段,并根据条件执行$$DESCEND$$PRUNE

使用$ifNull运算符可以通过比较替换用户ID($redact来继续第一个文档级别的$user(没有new ObjectId(req.user._id)字段) )new ObjectId(req.user._id)的值,以便您$$DESCEND可以嵌入文档级别以进行进一步处理。

更新

带有$project

$filter似乎比$redact更合适。像

这样的东西
{
    $project: {
    _id: 1,
    teacher: 1,
    course: 1,
    name: 1,
    submission: {
            $filter: {
                input: "$submission",
                as: "result",
                cond: {
                    $eq: ["$$result.user", new ObjectId(req.user._id)]
                }
            }
        }
    }
}
相关问题