MongoDB如何引用数组实现学生与课程集合关联查询获取对应成绩
问题原因&解决方法
错误点梳理
- 插入courses集合时,
grades字段被定义为字符串格式,而非MongoDB支持的原生数组结构,无法直接做嵌套字段匹配 grades数组内的student_id为数字类型,但students集合的_id是字符串类型,字段类型不匹配无法关联- 原有聚合的
$lookup直接匹配courses集合的顶层student_id字段,实际该字段嵌套在grades数组内,没有匹配项自然返回空数组
修正步骤
1. 修正courses集合插入代码
把grades从字符串改为原生数组,统一student_id为字符串类型,和students集合的_id类型匹配:
from pymongo import MongoClient import pprint client = MongoClient("mongodb://127.0.0.1:27017") db = client.Database course = [{"_id":"10", "coursename":"Databases", # 去掉外层引号改为原生数组,student_id改为字符串类型 "grades":[{"student_id":"0", "grade":83.442}, {"student_id":"1", "grade":45.323}, {"student_id":"2", "grade":87.435}]}] courses = db.courses courses.insert_many(course) pprint.pprint(courses.find_one())
2. 修正聚合查询代码
使用带嵌套pipeline的$lookup,匹配grades数组内对应当前学生的成绩,再重组输出结构:
from pymongo import MongoClient import pprint client = MongoClient("mongodb://127.0.0.1:27017") db = client["Database"] pipeline = [ # 优先匹配目标学生,减少后续计算量 { "$match": { "_id": "0" } }, { "$lookup": { "from": "courses", "let": {"student_id": "$_id"}, "pipeline": [ # 拆分grades数组 {"$unwind": "$grades"}, # 匹配对应当前学生的成绩 {"$match": {"$expr": {"$eq": ["$grades.student_id", "$$student_id"]}}}, # 重组字段符合输出要求 {"$project": { "coursename": 1, "student_id": "$grades.student_id", "grade": "$grades.grade" }} ], "as": "student_course" } } ] pprint.pprint(list(db.students.aggregate(pipeline)))
执行上述代码后即可得到你期望的输出结果。
内容的提问来源于stack exchange,提问作者MadVags
相关产品推荐
相关产品推荐

