MongoDB 连接多个集合、组、排序推送数组并重组结果的查询
MongoDB query that joins multiple collections, groups, sorts push array and restructures the result
MongoDB游乐场linkhere。下面列出了 Data
和 Desired Result
。学生可以一次又一次地学习同一门课程。我希望结果将学生与 _id: 1
匹配,然后按课程分组,然后按学期开始日期排序,并且仅 return 最近学期。这可能吗?
数据
db={
registers: [
{
_id: 1,
student: 1,
school: 1,
course: 1,
semester: 1,
grade: 59
},
{
_id: 2,
student: 1,
school: 1,
course: 1,
semester: 2,
grade: 99
},
{
_id: 3,
student: 1,
school: 2,
course: 2,
semester: 3,
grade: 100
}
],
students: [
{
_id: 1,
name: "Student1"
},
{
_id: 2,
name: "Student2"
}
],
schools: [
{
_id: 1,
name: "Zefram Cochrane High School"
},
{
_id: 2,
name: "Star Fleet Academy"
}
],
courses: [
{
_id: 1,
name: "Warp Theory"
},
{
_id: 2,
name: "Temporal Mechanics"
}
],
semesters: [
{
_id: 1,
name: "Fall 2320",
startDate: ISODate("2320-02-01"),
endDate: ISODate("2320-05-31")
},
{
_id: 2,
name: "Fall 2320",
startDate: ISODate("2320-09-01"),
endDate: ISODate("2320-12-31")
},
{
_id: 3,
name: "Spring 2321",
startDate: ISODate("2321-02-01"),
endDate: ISODate("2321-05-31")
}
]
}
期望的结果
[
{
"course": {
"name": "Warp Theory"
},
"grade": 99,
"school": {
"name": "Zefram Cochrane High School"
},
"semester": {
"endDate": ISODate("2320-12-31T00:00:00Z"),
"name": "Fall 2320",
"startDate": ISODate("2320-09-01T00:00:00Z")
},
"student": {
"name": "Student1"
}
},
{
"course": {
"name": "Temporal Mechanics"
},
"grade": 100,
"school": {
"name": "Star Fleet Academy"
},
"semester": {
"endDate": ISODate("2321-05-31T00:00:00Z"),
"name": "Spring 2321",
"startDate": ISODate("2321-02-01T00:00:00Z")
},
"student": {
"name": "Student1"
}
}
]
我将简要介绍这些变化:
- 过滤最大开始日期
- 包含的成绩
- 已尝试稍微改进您要求的格式。
(可以回滚)
输出
[
{
"course": "Warp Theory",
"grade": 99,
"school": "Zefram Cochrane High School",
"semester": {
"endDate": ISODate("2320-12-31T00:00:00Z"),
"startDate": ISODate("2320-09-01T00:00:00Z")
},
"student": "Student1"
},
{
"course": "Temporal Mechanics",
"grade": 100,
"school": "Star Fleet Academy",
"semester": {
"endDate": ISODate("2321-05-31T00:00:00Z"),
"startDate": ISODate("2321-02-01T00:00:00Z")
},
"student": "Student1"
}
]
管道
db.registers.aggregate([
{
$match: {
student: 1
}
},
{
$lookup: {
from: "students",
localField: "student",
foreignField: "_id",
as: "student"
}
},
{
$unwind: "$student"
},
{
$lookup: {
from: "schools",
localField: "school",
foreignField: "_id",
as: "school"
}
},
{
$unwind: "$school"
},
{
$lookup: {
from: "courses",
localField: "course",
foreignField: "_id",
as: "course"
}
},
{
$unwind: "$course"
},
{
$lookup: {
from: "semesters",
localField: "semester",
foreignField: "_id",
as: "semester"
},
},
{
$unwind: "$semester"
},
{
"$addFields": {
"semester.grade": "$grade"
}
},
{
$group: {
_id: {
course: "$course.name",
school: "$school.name",
student: "$student.name"
},
semester: {
$push: "$semester"
},
max: {
$max: "$semester.startDate"
}
}
},
{
$addFields: {
course: "$_id.course",
school: "$_id.school",
student: "$_id.student",
semester: {
$filter: {
input: "$semester",
as: "s",
cond: {
$eq: [
"$$s.startDate",
"$max"
]
}
}
}
}
},
{
$addFields: {
"grade": "$semester.grade"
}
},
{
$unset: [
"max",
"_id",
"semester._id",
"semester.grade",
"semester.name"
]
},
{
$unwind: "$semester"
},
{
$unwind: "$grade"
}
])
MongoDB游乐场linkhere。下面列出了 Data
和 Desired Result
。学生可以一次又一次地学习同一门课程。我希望结果将学生与 _id: 1
匹配,然后按课程分组,然后按学期开始日期排序,并且仅 return 最近学期。这可能吗?
数据
db={
registers: [
{
_id: 1,
student: 1,
school: 1,
course: 1,
semester: 1,
grade: 59
},
{
_id: 2,
student: 1,
school: 1,
course: 1,
semester: 2,
grade: 99
},
{
_id: 3,
student: 1,
school: 2,
course: 2,
semester: 3,
grade: 100
}
],
students: [
{
_id: 1,
name: "Student1"
},
{
_id: 2,
name: "Student2"
}
],
schools: [
{
_id: 1,
name: "Zefram Cochrane High School"
},
{
_id: 2,
name: "Star Fleet Academy"
}
],
courses: [
{
_id: 1,
name: "Warp Theory"
},
{
_id: 2,
name: "Temporal Mechanics"
}
],
semesters: [
{
_id: 1,
name: "Fall 2320",
startDate: ISODate("2320-02-01"),
endDate: ISODate("2320-05-31")
},
{
_id: 2,
name: "Fall 2320",
startDate: ISODate("2320-09-01"),
endDate: ISODate("2320-12-31")
},
{
_id: 3,
name: "Spring 2321",
startDate: ISODate("2321-02-01"),
endDate: ISODate("2321-05-31")
}
]
}
期望的结果
[
{
"course": {
"name": "Warp Theory"
},
"grade": 99,
"school": {
"name": "Zefram Cochrane High School"
},
"semester": {
"endDate": ISODate("2320-12-31T00:00:00Z"),
"name": "Fall 2320",
"startDate": ISODate("2320-09-01T00:00:00Z")
},
"student": {
"name": "Student1"
}
},
{
"course": {
"name": "Temporal Mechanics"
},
"grade": 100,
"school": {
"name": "Star Fleet Academy"
},
"semester": {
"endDate": ISODate("2321-05-31T00:00:00Z"),
"name": "Spring 2321",
"startDate": ISODate("2321-02-01T00:00:00Z")
},
"student": {
"name": "Student1"
}
}
]
我将简要介绍这些变化:
- 过滤最大开始日期
- 包含的成绩
- 已尝试稍微改进您要求的格式。 (可以回滚)
输出
[
{
"course": "Warp Theory",
"grade": 99,
"school": "Zefram Cochrane High School",
"semester": {
"endDate": ISODate("2320-12-31T00:00:00Z"),
"startDate": ISODate("2320-09-01T00:00:00Z")
},
"student": "Student1"
},
{
"course": "Temporal Mechanics",
"grade": 100,
"school": "Star Fleet Academy",
"semester": {
"endDate": ISODate("2321-05-31T00:00:00Z"),
"startDate": ISODate("2321-02-01T00:00:00Z")
},
"student": "Student1"
}
]
管道
db.registers.aggregate([
{
$match: {
student: 1
}
},
{
$lookup: {
from: "students",
localField: "student",
foreignField: "_id",
as: "student"
}
},
{
$unwind: "$student"
},
{
$lookup: {
from: "schools",
localField: "school",
foreignField: "_id",
as: "school"
}
},
{
$unwind: "$school"
},
{
$lookup: {
from: "courses",
localField: "course",
foreignField: "_id",
as: "course"
}
},
{
$unwind: "$course"
},
{
$lookup: {
from: "semesters",
localField: "semester",
foreignField: "_id",
as: "semester"
},
},
{
$unwind: "$semester"
},
{
"$addFields": {
"semester.grade": "$grade"
}
},
{
$group: {
_id: {
course: "$course.name",
school: "$school.name",
student: "$student.name"
},
semester: {
$push: "$semester"
},
max: {
$max: "$semester.startDate"
}
}
},
{
$addFields: {
course: "$_id.course",
school: "$_id.school",
student: "$_id.student",
semester: {
$filter: {
input: "$semester",
as: "s",
cond: {
$eq: [
"$$s.startDate",
"$max"
]
}
}
}
}
},
{
$addFields: {
"grade": "$semester.grade"
}
},
{
$unset: [
"max",
"_id",
"semester._id",
"semester.grade",
"semester.name"
]
},
{
$unwind: "$semester"
},
{
$unwind: "$grade"
}
])