文档数组字段每个元素的MongoDB聚合
我有两个系列- 学生资料集(学生资料样本) 主题收集(2份样本文档) 当我查询id为“123”的学生文档时,我希望结果输出为:文档数组字段每个元素的MongoDB聚合,mongodb,join,aggregation-framework,Mongodb,Join,Aggregation Framework,我有两个系列- 学生资料集(学生资料样本) 主题收集(2份样本文档) 当我查询id为“123”的学生文档时,我希望结果输出为: { 'id': '123', 'name': 'john', 'age': 25, 'fav_colors': ['red', 'black'], 'marks_in_subjects': [ { 'marks': 90, 'subject_id': 'abc', 'subject_name': 'math' },
{
'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聚合管道的帮助下是否可以实现,因为在这里,学生文档中数组字段的每个元素都会发生连接
如果有人能帮上忙,那就太好了。谢谢$match
解构$unwind
数组主题中的标记
与$lookup
集合主题
从返回主题获取第一个元素$addFields
name
by$group
并重建id
数组,还可以使用标记\u主题中的\u
操作符添加根文档的必填字段$first
第二个选项,不带
$unwind
阶段
$match
与$lookup
集合主题
从$addFields
主题
迭代$map
主题中标记的循环
迭代$reduce
数组,检查条件是否主题的循环
匹配,然后返回主题主题id
名称
将$mergeObjects
和新字段标记的当前对象合并到\u subject
subject\u name
删除$unset
数组,因为现在不需要它主题
$match
解构$unwind
数组主题中的标记
与$lookup
集合主题
从返回主题获取第一个元素$addFields
name
by$group
并重建id
数组,还可以使用标记\u主题中的\u
操作符添加根文档的必填字段$first
第二个选项,不带
$unwind
阶段
$match
与$lookup
集合主题
从$addFields
主题
迭代$map
主题中标记的循环
迭代$reduce
数组,检查条件是否主题的循环
匹配,然后返回主题主题id
名称
将$mergeObjects
和新字段标记的当前对象合并到\u subject
subject\u name
删除$unset
数组,因为现在不需要它主题
嘿@turivishal-谢谢你,伙计。成功了。谢谢。然而,我还有一个疑问。假设students集合中也有name字段,那么如何在输出文档中也获得name字段?我知道有一种解决方案可以在管道的分组阶段推送名称字段。但是,它将名称字段设置为数组。如何在输出中添加名称字段作为键值字段?您只需要名称字段或其他必需字段?我的意思是,我希望原始文档中的所有其他字段都保留在最终生成的文档中。因此,如果原始的students文档有n个其他字段,我希望在将主题名称添加到marks in subject字段中后,它们将保留在最终生成的文档中。我希望我是清楚的。再次感谢您抽出时间来讨论这个问题。您可以展示您的预期结果吗?只需更改游乐场的结果并在此处共享。@Turivshal-我已更新了问题详细信息中的输入和输出:)嘿@Turivshal-谢谢老兄。成功了。谢谢。然而,我还有一个疑问。假设students集合中也有name字段,那么如何在输出文档中也获得name字段?我知道有一种解决方案可以在管道的分组阶段推送名称字段。但是,它将名称字段设置为数组。如何在输出中添加名称字段作为键值字段?您只需要名称字段或其他必需字段?我的意思是,我希望原始文档中的所有其他字段都保留在最终生成的文档中。因此,如果原始的students文档有n个其他字段,我希望在将主题名称添加到marks in subject字段中后,它们将保留在最终生成的文档中。我希望我是清楚的。再次感谢您给我时间。您能不能只显示您的预期结果,只需更改游乐场的结果并在此处共享。@turivishal-我已更新了问题详细信息中的输入和输出:)
{
'id': 'abc',
'name': 'math'
},
{
'id': 'def',
'name': 'physics'
}
{
'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'
}
]
}
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" }
}
}
])
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" }
])
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" }
}
}
])