MongoDB无法填充Go嵌套结构体问题求助
问题分析与解决方案
你遇到的问题本质是mgo库在反序列化bson到结构体时,不会自动初始化嵌入的指针类型字段。当你查询PressRelease文档时,根文档的_id能被正确填充,但*ContactInfo和*Content这两个指针字段因为没有预先分配内存,始终保持nil,自然无法填充它们内部的属性。
解决方案有两种,你可以根据需求选择:
方案1:将嵌入字段改为值类型(推荐,更简单)
把PressRelease里的指针嵌入改成值类型嵌入,mgo会自动初始化这些值类型结构体,并将根文档中对应的平级字段映射进去:
// PressRelease is a document in MongoDB type PressRelease struct { ID bson.ObjectId `json:"_id" bson:"_id"` ContactInfo ContactInfo `json:"-" bson:"-"` // 保持匿名嵌入,bson/json字段平级 Content Content `json:"-" bson:"-"` }
注意:因为是匿名嵌入,文档中的
timestamp、persons等字段会直接映射到嵌入结构体的对应属性上,不需要额外修改bson字段名。
方案2:预先初始化指针字段(适合必须用指针的场景)
如果你的业务逻辑依赖指针类型嵌入,可以在查询前手动为指针分配内存,这样mgo就能把数据填充到已存在的结构体实例中:
func (mc mongoClient) ListRecentUnhandled(c context.Context) (*api.PressRelease, error) { // 预先初始化嵌入的指针字段 pr := &api.PressRelease{ ContactInfo: new(api.ContactInfo), Content: new(api.Content), } err := mc.Find(nil).Sort("-timestamp").One(pr) return pr, err }
为什么测试用例无法复现?
大概率是你在测试用例中手动构造PressRelease时,已经初始化了这些指针字段,或者使用了json序列化(json库在某些场景下的行为和mgo略有不同),所以没有触发这个问题。
内容的提问来源于stack exchange,提问作者Louis Thibault
相关产品推荐
相关产品推荐

