为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕丝7291255 2021-11-08 16:07:49
下面我设计的文档结构如下: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的school_name>找到crse_list的dept_name>查找crse_name之所以需要这样的发现链,是因为发现的范围应该仅限于学校,然后是部门。逻辑和内务处理发生在发现的每个阶段之后。我试过代码,如result := MIS_School{}err := database.C("schools").Find(bson.M{"school_name": school}).Select(bson.M{"dept_list": bson.M{"$elemMatch": bson.M{"dept_name": dept}}}).Select(bson.M{"crse_list": bson.M{"$elemMatch": bson.M{"crse_name": crse}}}).One(&result)但它不起作用,因为 Select 投影不能在 Mgo(?)我从某处读到 mongodb 没有能力直接检索嵌套在深度超过 1-2 级的数组中的文档(在 A 数组中的 B 数组中获取文档 C)。真的吗?我该如何解决这个问题?
查看完整描述

2 回答

?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

您可以链接 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",

    }

不过,您可以以任意方式更改结果对象的形状。有关更多详细信息,请查看聚合框架文档。


查看完整回答
反对 回复 2021-11-08
?
largeQ

TA贡献2039条经验 获得超7个赞

阅读蒙戈文档后,我认为做嵌套关系的首选方法是用物化路径用树形结构描述这里的蒙戈。

还可以使用祖先父/子引用数组的树。看一看。

似乎使用树更简单、更优雅,并且省去了很多技术麻烦。


查看完整回答
反对 回复 2021-11-08
  • 2 回答
  • 0 关注
  • 175 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信