根据子ID查找父文档

时间:2017-06-07 19:56:48

标签: mongodb mongoose left-join grouping

假设我有以下架构

let TutorialQuizSchema = new mongoose.Schema({
    groups: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Group' }]
});

let GroupSchema = new mongoose.Schema({
    members: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }],
    responses: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Response' }]
});

let UserSchema = new mongoose.Schema({
    name: {
        first: String,
        last: String
    }
});

如果有用户ID,是否可以使用将该用户作为其成员之一的所有组查询所有教程测验?

我是聚合新手,但我认为它会是这样的

TutorialQuiz.aggreggate([
    {
        $unwind: '$groups'
    },
    { 
        $lookup: {
            from: 'groups',
            localField: 'groups',
            foreignField: '_id',
            as: 'group'
        }
    },
    {
        $unwind: '$group'
    },
    {
        $match: { 
            'group.members': { $in: [req.user._id] } 
        }
    }
]).exec((err, data) => {
    // etc
})

如果我是对的,我唯一的问题就是数据变平了。是否可以解除它以维持层次结构(就像我们只是在进行find + populate查询一样)?

注意:如果有更好/更简单的方法,我也愿意接受建议。

1 个答案:

答案 0 :(得分:1)

$lookup可以直接$unwind objectIds $filter并在$unwind阶段内使用$addFields代替第二user_id来过滤{ {1}}在3.4版本的members数组中的值。

这样的东西
TutorialQuiz.aggreggate([
    { 
        $lookup: {
            from: 'groups',
            localField: 'groups',
            foreignField: '_id',
            as: 'group'
        }
    },
    {
      $addFields: {
         group: {
            $filter: {
               input: "$group",
               as: "group",
               cond: { $in: [ req.user._id, "$$group.members" ] }
            }
         }
      }
   }
])