【问题标题】:How to compose a complex query using resultset from another query in Mongodb?如何使用来自 Mongodb 中另一个查询的结果集来组成一个复杂的查询?
【发布时间】:2021-08-10 14:28:00
【问题描述】:

我正在使用 Mongo(使用 Mongo 本机驱动程序)、Node 和 Express 编写应用程序。

我在 mongo 中有学生、课程和教授文档。

我想检索学生当前正在学习或过去学习过的所有“教授”文档的列表。

Students: {courseid, ....}
Course: {professors, ....}
Professors: {....}

这是我打算做的:

  1. 我首先发出一个查询来检索学生的所有课程 ID。
  2. 然后我必须编写并发出另一个查询以获取所有这些课程的教授 ID。
  3. 最后我必须获取与教授 ID 关联的所有“教授”文档。

第 1 步没问题,现在我有了所有课程 ID。但我不确定如何执行第 2 步。第二步和第三步是类似的,一旦我弄清楚第二步,第三步就很容易了。

基本上我想在步骤 2 中发出一个查询来检索所有教授 ID。我不想针对 10 个课程 ID 发出 10 个单独的查询。

这是我所拥有的:

function getProfsByStudent(req, res, next)
{
  db.collection('students', function(err, stuColl)
  {
    stuId = new ObjectID.createFromHexString(req.params.stuId);
    stuColl.find({_id : userId}, { 'current_course_id' : 1 , 'past_courses.course_id' : 1 , _id : 0 })
    {
      db.collection('courses', function(err, courseColl)
      {
        courseColl.find({$or : []}) // THIS IS WHERE I AM STUCK
      });
      res.send(posts);
    });
  });
}

更新

根据答案更新问题。

所以,这是我在stuColl.find 调用之后得到的 JSON:

[{"current_course_id":"4f7fa4c37c06191111000005","past_courses":[{"course_id":"4f7fa4c37c06191111000003"},{"course_id":"4f7fa4c37c06191111000002"}]}]

现在我想用上面的方法做另一个查找来获取所有教授的 ID。但我得到的只是一个空结果。我认为我非常接近。我做错了什么?

stuColl.find({_id : userId}, { 'current_course_id' : 1 , 'past_courses.course_id' : 1 , _id : 0 }).toArray(function(err, courseIdsArray)
        {
            db.collection('courses', function(err, courseColl)
            {
                courseColl.find({$or : [ {_id : 'courseIdsArray.current_courses_id' }, {_id : {$in : courseIdsArray.past_courses}} ]}, {'professor_ids' : 1}).toArray(function(err, professorIdsArray)
                {
                  res.send(professorIdsArray);
                });
            });
        });

【问题讨论】:

    标签: node.js mongodb express


    【解决方案1】:

    我认为您应该使用 $in 运算符而不是 $or

    http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24in

    和:

    stuColl.find....
    

    应该返回其结果toArray 以用于$in 运算符。

    更新

    我想这就是你要找的东西:

    db.collection("Students").find({_id : "8397c60d-bd7c-4f94-a0f9-f9db2f14e8ea"}, {CurrentCourses:1, PastCourses : 1, _id : 0}).toArray(function(err, allCourses){
        if(err){
            //error handling
        }
        else{           
            var courses = allCourses[0].CurrentCourses.concat(allCourses[0].PastCourses);           
            db.collection("Courses").find({ _id : { $in: courses}}, {"Professors" : 1, _id : 0}).toArray(function(err, professors){ 
                if(err){
                    //error handling
                }
                var allProfs = [];
                for(var i = 0; i < professors.length; i++){
                    allProfs = allProfs.concat(professors[i].Professors);
                }
                db.collection("Professors").find({ _id : { $in: allProfs }}).toArray(function(err, results){
                    console.log(results);
                });
            });         
        }
    });
    

    它通过学生集合找到学生,然后通过他/她的所有课程最终加载所有教师。

    【讨论】:

    • coffeeyesplease,感谢您的回复。从代码中可以看出,stuColl.find 将返回一个顶级 courseid,并且还可能包含一个嵌入的 course id 数组。 $in 可以同时查看这两个级别吗?还是 toArray 能够将多级结果展平为 1 级对象 ID 数组?如果不是什么是这样做的好方法?苏
    • 回答你的问题,没有 mongo 不会把它弄平。如果这确实是您正在寻找的东西,那么 mapReduce 函数可能会为您提供帮助。让我知道这是否有帮助。
    猜你喜欢
    • 2019-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 2022-01-09
    • 2019-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多