如何使用聚合匹配猫鼬中两个集合中的数据?

时间:2021-03-30 09:07:04

标签: node.js mongodb express mongoose

我有一个测验应用程序,其中的架构如下: 测验架构 -

const quizSchema = new mongoose.Schema({
  userID: {
    type: String,
    required: [true, 'User ID required']
  }
});

响应架构 -

const responseSchema = new mongoose.Schema({
  userID: {
    type: String,
    required: [true, 'User ID required']
  },
  quizID: {
    type: String,
    required: [true, 'Quiz ID required']
  }
});

响应架构包含用户对测验的响应,即如果尝试进行测验,则仅将其存储在响应架构中

我可以很容易地找出用户尝试使用的测验

const attempted = await Response.find({userID});

这是我如何使用基本逻辑做到的:-

exports.unattemptedQuizDB = async (userID) => {
    try{
        const quizzes = await Quiz.find({});
        const filtered = [];
        for (const quiz of quizzes){
            const inResponse = await Response.find({userID:userID, quizID: quiz._id});
            if (inResponse.length === 0){
                filtered.push(quiz._id);
            }
        }
        return filtered;
    }catch(e){
        throw new Error(e);
    }
};

但是我如何使用聚合找到无人尝试的测验?

1 个答案:

答案 0 :(得分:1)

以下是您编写的逻辑的聚合查询:

let responses = await Quiz.aggregate([
    {
        $lookup: {
            from: "responses",
            let: { 
                userID: "$userID", 
                quizID: { $toString: "$_id" }
            },
            pipeline: [
                {
                    $match: {
                        $expr: {
                            $and: [
                                { $eq: ["$userID", "$$userID"] },
                                { $eq: ["$quizID", "$$quizID"] }
                            ]
                        }
                    }
                }
            ],
            as: "responses"
        }
    },
    {
        $match: {
            "responses": { $eq: [] }
        }
    }
]);