我有 2 个集合 -
学生合集(学生文档样本)
{
'id': '123',
'name': 'john',
'age': 25,
'fav_colors': ['red', 'black'],
'marks_in_subjects': [
{
'marks': 90,
'subject_id': 'abc'
},
{
'marks': 92,
'subject_id': 'def'
}
]
}
主题集合(2 个示例文档)
{
'id': 'abc',
'name': 'math'
},
{
'id': 'def',
'name': 'physics'
}
当我查询学生文档的 id: '123' 时,我希望结果输出为:
{
'id': '123',
'name': 'john',
'age': 25,
'fav_colors': ['red', 'black'],
'marks_in_subjects': [
{
'marks': 90,
'subject_id': 'abc',
'subject_name': 'math'
},
{
'marks': 92,
'subject_id': 'def',
'subject_name': 'physics'
}
]
}
现在,我阅读了 MongoDB 聚合管道和运算符文档,但我仍然不知道如何实现这一点。疑问仍然存在,因为我什至不确定在 mongo 聚合管道的帮助下这是否可行,因为 JOIN 在这里针对学生文档中数组字段的每个元素发生。
如果有人能在这里提供帮助,那将非常有帮助。谢谢
答案 0 :(得分:3)
演示 - https://mongoplayground.net/p/H5fHpfWz5VH
db.Students.aggregate([
{
$unwind: "$marks_in_subjects" // break into individual documents
},
{
"$lookup": { // get subject details
"from": "Subjects",
"localField": "marks_in_subjects.subject_id",
"foreignField": "id",
"as": "subjects"
}
},
{
$set: { // set name
"marks_in_subjects.name": "subjects.0.name" // pick value from 0 index
}
},
{
$group: { // join document back by id
_id: "$_id",
marks_in_subjects: { $push: "$marks_in_subjects" }
}
}
])
答案 1 :(得分:2)
$match
你有条件$unwind
解构 marks_in_subjects
数组$lookup
与 subjects
集合$addFields
从返回主题中获取第一个元素 name
$group
by id
并重建 marks_in_subjects
数组,并使用 $first
运算符添加您所需的根文档字段db.students.aggregate([
{ $match: { id: "123" } },
{ $unwind: "$marks_in_subjects" },
{
$lookup: {
from: "subjects",
localField: "marks_in_subjects.subject_id",
foreignField: "id",
as: "marks_in_subjects.subject_name"
}
},
{
$addFields: {
"marks_in_subjects.subject_name": {
$arrayElemAt: ["$marks_in_subjects.subject_name.name", 0]
}
}
},
{
$group: {
_id: "$id",
name: { $first: "$name" },
age: { $first: "$age" },
fav_colors: { $first: "$fav_colors" },
marks_in_subjects: { $push: "$marks_in_subjects" }
}
}
])
没有 $unwind
阶段的第二个选项,
$match
你有条件$lookup
与 subjects
集合$addFields
从 subjects
获取主题名称
$map
迭代 marks_in_subjects
数组的循环$reduce
迭代 subjects
数组的循环并检查条件,如果 subject_id
匹配,则返回主题 name
$mergeObjects
合并 marks_in_subjects
的当前对象和新字段 subject_name
$unset
删除 subjects
数组,因为它现在不需要db.students.aggregate([
{ $match: { id: "123" } },
{
$lookup: {
from: "subjects",
localField: "marks_in_subjects.subject_id",
foreignField: "id",
as: "subjects"
}
},
{
$addFields: {
marks_in_subjects: {
$map: {
input: "$marks_in_subjects",
as: "m",
in: {
$mergeObjects: [
"$$m",
{
subject_name: {
$reduce: {
input: "$subjects",
initialValue: "",
in: {
$cond: [{ $eq: ["$$this.id", "$$m.subject_id"]}, "$$this.name", "$$value"]
}
}
}
}
]
}
}
}
}
},
{ $unset: "subjects" }
])