将不同列的值投影到一个字段中
Project values of different columns into one field
{
"_id" : ObjectId("5ae84dd87f5b72618ba7a669"),
"main_sub" : "MATHS",
"reporting" : [
{
"teacher" : "ABC"
}
],
"subs" : [
{
"sub" : "GEOMETRIC",
"teacher" : "XYZ",
}
]
}
{
"_id" : ObjectId("5ae84dd87f5b72618ba7a669"),
"main_sub" : "SOCIAL SCIENCE",
"reporting" : [
{
"teacher" : "XYZ"
}
],
"subs" : [
{
"sub" : "CIVIL",
"teacher" : "ABC",
}
]
}
我已经简化了现有文档的结构。
基本结构是我有一个父主题,其中包含一系列报告教师和一系列子主题(每个子主题都有一位老师)
我现在想提取所有科目(parent/sub-subjects)以及条件,如果它们是不是由特定老师教授的子科目。
例如:
对于 ABC 老师,我想要以下结构:
[{'subject':'MATHS', 'is_parent':'True'}, {'subject':'CIVIL', 'is_parent':'FALSE'}]
-- 最有效的查询是什么..?我已经用 $cond 和 $switch 尝试了 $project 但在这两种情况下我都不得不重复 'subject' 和 'is_parent'
的条件语句
-- 是否建议在查询中进行计算,或者我应该获取数据转储然后修改服务器代码中的结构?如,我可以 $unwind 并获得父主题与每个子主题的映射,然后执行 for 循环。
我试过了
db.collection.aggregate(
{$unwind:'$reporting'},
{$project:{
'result':{$cond:[
{$eq:['ABC', '$reporting.teacher']},
"$main_sub",
"$subs.sub"]}
}}
)
然后我意识到,即使我将 else 部分转换为子主题的另一个查询,我也必须为 is_parent[=13= 的 属性 编写完全相同的内容]
您有 2 个数组,因此您需要同时展开 - reporting
和 subs
。
在那个阶段之后,每个文档将最多有 1 个父 teacher-subj 和最多 1 个 sub teacher-subj 对。
您需要再次展开它们以使每个文档只有一个 teacher-subj,并且您可以在其中定义它是否为父项。
然后就可以按老师分组了。不需要 $conds、$filters 或 $facets。例如:
db.collection.aggregate([
{ $unwind: "$reporting" },
{ $unwind: "$subs" },
{ $project: {
teachers: [
{ teacher: "$reporting.teacher", sub: "$main_sub", is_parent: true },
{ teacher: "$subs.teacher", sub: "$subs.sub", is_parent: false }
]
} },
{ $unwind: "$teachers" },
{ $group: {
_id: "$teachers.teacher",
subs: { $push: {
subject: "$teachers.sub",
is_parent: "$teachers.is_parent"
} }
} }
])
{
"_id" : ObjectId("5ae84dd87f5b72618ba7a669"),
"main_sub" : "MATHS",
"reporting" : [
{
"teacher" : "ABC"
}
],
"subs" : [
{
"sub" : "GEOMETRIC",
"teacher" : "XYZ",
}
]
}
{
"_id" : ObjectId("5ae84dd87f5b72618ba7a669"),
"main_sub" : "SOCIAL SCIENCE",
"reporting" : [
{
"teacher" : "XYZ"
}
],
"subs" : [
{
"sub" : "CIVIL",
"teacher" : "ABC",
}
]
}
我已经简化了现有文档的结构。 基本结构是我有一个父主题,其中包含一系列报告教师和一系列子主题(每个子主题都有一位老师)
我现在想提取所有科目(parent/sub-subjects)以及条件,如果它们是不是由特定老师教授的子科目。
例如:
对于 ABC 老师,我想要以下结构:
[{'subject':'MATHS', 'is_parent':'True'}, {'subject':'CIVIL', 'is_parent':'FALSE'}]
-- 最有效的查询是什么..?我已经用 $cond 和 $switch 尝试了 $project 但在这两种情况下我都不得不重复 'subject' 和 'is_parent'
的条件语句-- 是否建议在查询中进行计算,或者我应该获取数据转储然后修改服务器代码中的结构?如,我可以 $unwind 并获得父主题与每个子主题的映射,然后执行 for 循环。
我试过了
db.collection.aggregate(
{$unwind:'$reporting'},
{$project:{
'result':{$cond:[
{$eq:['ABC', '$reporting.teacher']},
"$main_sub",
"$subs.sub"]}
}}
)
然后我意识到,即使我将 else 部分转换为子主题的另一个查询,我也必须为 is_parent[=13= 的 属性 编写完全相同的内容]
您有 2 个数组,因此您需要同时展开 - reporting
和 subs
。
在那个阶段之后,每个文档将最多有 1 个父 teacher-subj 和最多 1 个 sub teacher-subj 对。
您需要再次展开它们以使每个文档只有一个 teacher-subj,并且您可以在其中定义它是否为父项。
然后就可以按老师分组了。不需要 $conds、$filters 或 $facets。例如:
db.collection.aggregate([
{ $unwind: "$reporting" },
{ $unwind: "$subs" },
{ $project: {
teachers: [
{ teacher: "$reporting.teacher", sub: "$main_sub", is_parent: true },
{ teacher: "$subs.teacher", sub: "$subs.sub", is_parent: false }
]
} },
{ $unwind: "$teachers" },
{ $group: {
_id: "$teachers.teacher",
subs: { $push: {
subject: "$teachers.sub",
is_parent: "$teachers.is_parent"
} }
} }
])