下面我的文档结构设计如下:
type MIS_Course struct {
ID bson.ObjectId `bson:"_id,omitempty"`
Name string `bson:"crse_name"`
}
type MIS_Department struct {
ID bson.ObjectId `bson:"_id,omitempty"`
Name string `bson:"dept_name"`
Courses []MIS_Course `bson:"crse_list"`
}
type MIS_School struct {
ID bson.ObjectId `bson:"_id,omitempty"`
Name string `bson:"school_name"`
Departments []MIS_Department `bson:"dept_list"`
}
当初始化时,我会有一个"学校ABC"在学校的海洋中,包含如下所示的东西:
{
"_id" : ObjectId("55fbb522022aae7b3a000003"),
"school_name" : "School ABC",
"dept_list" : [
{
"dept_name" : "Department A",
"crse_list" : [
{
"crse_name" : "Class A"
},
{
"crse_name" : "Class B"
},
]
}
]
}
根据给定的school_name,dept_name和crse_name,我无法找到有效工作的解决方案:
找到dept_list
的{{1}}>找到school_name
的{{1}}>找到crse_list
需要这种发现链的原因是因为发现的范围应该限于学校,然后是部门。在发现的每个阶段之后发生逻辑和内务处理。
我尝试了诸如
之类的代码dept_name
但它没有用,因为Select投影无法在Mgo中链接(?)
我从某个地方读过,mongodb没有能力直接检索嵌套在1-2级以上数组中的文档(在A数组中的B数组中获取文档C)。真的吗?我怎么能解决这个问题?
谢谢!
答案 0 :(得分:1)
你可以链接Select语句,但是第二个调用的值将覆盖第一个调用的值,而不是执行示例所暗示的操作,这是深入了解嵌套结构。
要实现您正在尝试的功能,您可以使用聚合框架以任意方式操作这些嵌套对象。
例如,这是一个简单的管道,可以提取完全匹配的课程:
pipeline := []bson.M{
{"$match": bson.M{"school_name": school}},
{"$unwind": "$dept_list"},
{"$unwind": "$dept_list.crse_list"},
{"$match": bson.M{
"dept_list.dept_name": dept,
"dept_list.crse_list.crse_name": crse,
}},
}
iter := coll.Pipe(pipeline).Iter()
您可以像使用Find中的迭代器一样使用生成的迭代器。
对于此管道,生成的对象将如下所示:
bson.M{
"_id":"...",
"dept_list": bson.M{
"dept_name": "Department A",
"crse_list": bson.M{
"crse_name": "Class B",
}
},
"school_name":"School ABC",
}
但是,您可以以任意方式更改结果对象的形状。有关更多详细信息,请查看aggregation framework文档。
答案 1 :(得分:0)
在阅读mongo文档之后,我认为执行嵌套关系的首选方法是使用具有物理路径的树结构,如mongo上所述here。
还提供array of ancestors和parent / child references的树。看一看。
似乎使用树木更简单,更优雅,并且节省了很多技术上的麻烦。