当前位置: 首页 > 知识库问答 >
问题:

在第二个(学生)表中查找匹配所有传入输出记录的mongodb聚合时遇到问题

鲜于德业
2023-03-14

我遇到了与第一个(测试)表的所有传入输出记录匹配的第二个(学生)表中的查找问题。我有两个集合“测试”和“学生”。“测试”集合包含所有学校测试,“学生”表包含学生参加的测试。学生表包含“pastTest”(过去参加过的测试,状态为“通过”或“失败”)数组。我想检索通过所有传入测试的学生(我们从测试表中检索)

测试表:_id(初级ket)student.pastTests。testId(需要与test._id匹配)

测试文档:

{
    "_id" : ObjectId("5c9b5c1005729b2bf23f3290"),
    "testDate" : {
        "term" : 1,
        "week" : 7
    },
    "retestDate" : {
        "term" : 1,
        "week" : 10
    },
    "testOrder" : "1.1",
    "testDateScheduled" : true,
    "retestDateScheduled" : true
}

学生证件:

{
    "_id" : ObjectId("5c92dd994e8e6b2c1647d0d0"),
    "completedYears" : [],
    "firstName" : "Andrew",
    "lastName" : "Jonhson",
    "teacherId" : ObjectId("5bf36b1076696374e65feb4f"),
    "yearGroup" : "0",
    "schoolId" : 40001,
    "currentTest" : ObjectId("5c9b5c1005729b2bf23f3290"),
    "pastTests" : [ 
        {
           
            "_id" : ObjectId("5d3570645045863d373f6db1"),
            "testId" : ObjectId("5c9b5c1005729b2bf23f3290"),
            "status" : "pass"
        }, 
        {
           
            "_id" : ObjectId("5d425af07708f5636c3bec1c"),
            "testId" : ObjectId("5c9b5fc460e39c2c58e44109"),
            "status" : "pass"
        }, 
        {
            "_id" : ObjectId("5d5e54a875fab079f4d03570"),
            "testId" : ObjectId("5c9b6492bb581c2ceb553fef"),
            "status" : "fail"
        }, 
    ],
    "createdAt" : ISODate("2019-03-21T00:40:57.401Z"),
    "updatedAt" : ISODate("2020-09-24T19:55:38.291Z"),
    "__v" : 0,
    "holdTests" : [],
    "completedTests" : [],
    "className" : "dd",
}

查询:

db.getCollection('tests').aggregate([
     {
       $match: {
           yearGroup: '-1',
            $or : [
                {
                   $and: [
                    {'retestDateScheduled': true},
                    { 'retestDate.term': { $lt: 4 } },
                   ]
                },
                {
                   $and: [
                    {'testDateScheduled': true},
                    { 'testDate.term': { $lt: 4 } },
                   ]
                }
            ]
       }
     },
    {
      $lookup: {
        from: 'students',
        let: {testId: '$_id', schoolId: 49014, yearGroup: '-1'},
        pipeline: [
            
        ]
      }
    }
])

注意:初始匹配查询返回term-1的所有测试,现在我必须检索通过term-1所有测试的学生。

查找阶段待定-在第二个(学生)表中查找匹配第一个(测试)集合的所有传入输出记录时面临问题

提前致谢!!

共有1个答案

孙化
2023-03-14

试试这个:

db.tests.aggregate([
    {
        $match: {
            // Your match condition
        }
    },
    {
        $group: {
            _id: null,
            term_1_testIds: { $push: "$_id" },
            test_count: { $sum: 1 }
        }
    },
    {
        $lookup: {
            from: "students",
            let: { term_1_testIds: '$term_1_testIds', schoolId: 40001, totalTestCount: "$test_count" },
            pipeline: [
                {
                    $match: {
                        $expr: { $eq: ["$schoolId", "$$schoolId"] }
                    }
                },
                { $unwind: "$pastTests" },
                {
                    $match: {
                        "pastTests.status": "pass",
                        $expr: { $in: ["$pastTests.testId", "$$term_1_testIds"] }
                    }
                },
                {
                    $group: {
                        _id: "$_id",
                        firstName: { $first: "$firstName" },
                        yearGroup: { $first: "$yearGroup" },
                        schoolId: { $first: "$schoolId" },
                        currentTest: { $first: "$currentTest" },
                        passedTestCount: { $sum: 1 },
                        pastTests: { $push: "$pastTests" }
                    }
                },
                {
                    $match: {
                        $expr: { $eq: ["$passedTestCount", "$$totalTestCount"] }
                    }
                }
            ],
            as: "students"
        }
    }
]);

输出:

{
    "_id" : null,
    "term_1_testIds" : [
        ObjectId("5c9b5c1005729b2bf23f3290"),
        ObjectId("5c9b5fc460e39c2c58e44109"),
        ObjectId("5c9b6492bb581c2ceb553fef")
    ],
    "test_count" : 3,
    "students" : [
        {
            "_id" : ObjectId("5c92dd994e8e6b2c1647d0d1"),
            "firstName" : "Dheemanth",
            "yearGroup" : "0",
            "schoolId" : 40001,
            "currentTest" : ObjectId("5c9b5c1005729b2bf23f3290"),
            "passedTestCount" : 3,
            "pastTests" : [
                {
                    "_id" : ObjectId("5d3570645045863d373f6db1"),
                    "testId" : ObjectId("5c9b5c1005729b2bf23f3290"),
                    "status" : "pass"
                },
                {
                    "_id" : ObjectId("5d425af07708f5636c3bec1c"),
                    "testId" : ObjectId("5c9b5fc460e39c2c58e44109"),
                    "status" : "pass"
                },
                {
                    "_id" : ObjectId("5d5e54a875fab079f4d03570"),
                    "testId" : ObjectId("5c9b6492bb581c2ceb553fef"),
                    "status" : "pass"
                }
            ]
        }
    ]
}

这就是我的测试集合的样子

/* 1 createdAt:3/27/2019, 5:24:58 PM*/
{
    "_id" : ObjectId("5c9b6492bb581c2ceb553fef"),
    "name" : "Test 3"
},

/* 2 createdAt:3/27/2019, 5:04:28 PM*/
{
    "_id" : ObjectId("5c9b5fc460e39c2c58e44109"),
    "name" : "Test 2"
},

/* 3 createdAt:3/27/2019, 4:48:40 PM*/
{
    "_id" : ObjectId("5c9b5c1005729b2bf23f3290"),
    "name" : "Test 1"
}

这是我的< code >学生集合的样子:

/* 1 createdAt:3/21/2019, 6:10:57 AM*/
{
    "_id" : ObjectId("5c92dd994e8e6b2c1647d0d1"),
    "firstName" : "Dheemanth",
    "yearGroup" : "0",
    "schoolId" : 40001,
    "currentTest" : ObjectId("5c9b5c1005729b2bf23f3290"),
    "pastTests" : [
        {
            "_id" : ObjectId("5d3570645045863d373f6db1"),
            "testId" : ObjectId("5c9b5c1005729b2bf23f3290"),
            "status" : "pass"
        },
        {
            "_id" : ObjectId("5d425af07708f5636c3bec1c"),
            "testId" : ObjectId("5c9b5fc460e39c2c58e44109"),
            "status" : "pass"
        },
        {
            "_id" : ObjectId("5d5e54a875fab079f4d03570"),
            "testId" : ObjectId("5c9b6492bb581c2ceb553fef"),
            "status" : "pass"
        }
    ]
},

/* 2 createdAt:3/21/2019, 6:10:57 AM*/
{
    "_id" : ObjectId("5c92dd994e8e6b2c1647d0d0"),
    "firstName" : "Andrew",
    "yearGroup" : "0",
    "schoolId" : 40001,
    "currentTest" : ObjectId("5c9b5c1005729b2bf23f3290"),
    "pastTests" : [
        {
            "_id" : ObjectId("5d3570645045863d373f6db1"),
            "testId" : ObjectId("5c9b5c1005729b2bf23f3290"),
            "status" : "pass"
        },
        {
            "_id" : ObjectId("5d425af07708f5636c3bec1c"),
            "testId" : ObjectId("5c9b5fc460e39c2c58e44109"),
            "status" : "pass"
        },
        {
            "_id" : ObjectId("5d5e54a875fab079f4d03570"),
            "testId" : ObjectId("5c9b6492bb581c2ceb553fef"),
            "status" : "fail"
        }
    ]
}

另外:在您的第一个$match阶段,$和运算符在$或数组中是多余的,它应该是这样的:

{
    $match: {
        yearGroup: '-1',
        $or: [
            {
                'retestDateScheduled': true,
                'retestDate.term': { $lt: 4 }
            },
            {
                'testDateScheduled': true,
                'testDate.term': { $lt: 4 }
            }
        ]
    }
}
 类似资料:
  • 我想知道如何使用mongodb 3.2的java驱动程序对$lookup集合执行聚合$match。下面是我正在处理的两个集合的结构: 对两个 id (coll_one.foreign_id 的查找 这是我正在使用的Java代码: 当我移除火柴部分时,一切都很好。我尝试了这么多的可能性组合,但都没有成功!!! 有人能告诉我这是否可能吗????

  • 在mongodb聚合调用中,如何使用$group操作符将管道中的所有文档分组为一个结果? 假设我有一组记录,看起来像这样: 我想使用聚合函数在数据库中查询在给定日期范围内注册的用户列表,并将其作为列表返回。我想要一个如下的结果: 我的查询如下所示: 到目前为止,一切顺利。我现在有一部分记录,所有记录的注册日期都在所需的范围内。但这就是我遇到麻烦的地方。现在,我想将所有这些记录分组到一个包含所有ID

  • 问题内容: 嗨,我在下面的表格中记录了活动和分数 我需要从活动中返回所有记录 退货 然后我需要基于来自点表的用户ID对用户点求和 退货 一切都很好,但我需要将它们放在一起给用户,即 有指针吗? 问题答案: 使用外部联接: 或子查询:

  • 问题内容: 我试图实现使用中去(golang)我的MongoDB查询的一个功能氧化镁包。 以下是我的收藏: 资料夹: 文件: 以下是我编写的在外壳程序上成功运行的查询: 如果我在外壳上运行此脚本,则会得到所需的结果。基本上,集合会返回给我,其中包含通过链接的全部相关内容。我不在这里包括它,因为这个问题似乎已经太久了。 我试图将此查询转换为 mgo 能够解析和执行的内容。在下面的go代码中: 我总是

  • 是否可以在$match中执行OR? 我的意思是这样的:

  • 问题内容: 我需要一个activerecord查询来匹配params数组中的所有项目。 假设用户具有has_many个角色。每个角色都有一个名字 当我通过[‘演员’,’制作人’,’歌手’]时。我希望查询返回给我具有所有这三个角色或更多角色的用户。 但是我下面的方法实现将返回具有至少一个与传递的数组中的角色名称匹配的角色名称的用户 我当前的方法基于找到任何标签而不是“ MATCH ALL”来给出结果