Mgo如何在嵌套数组中找到嵌套文档?

时间:2015-09-18 12:35:10

标签: mongodb go mgo database

下面我的文档结构设计如下:

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)。真的吗?我怎么能解决这个问题?

谢谢!

2 个答案:

答案 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 ancestorsparent / child references的树。看一看。

似乎使用树木更简单,更优雅,并且节省了很多技术上的麻烦。