我有mongodb的以下架构:
package api
import (
"time"
"gopkg.in/mgo.v2/bson"
)
// Content of a press-release
type Content struct {
Timestamp time.Time `json:"timestamp" bson:"timestamp"`
PubDate time.Time `json:"pub_date" bson:"pub_date"`
Title string `json:"title" bson:"title"`
Description string `json:"description" bson:"description"`
Sector string `json:"sector" bson:"sector"`
}
// ContactInfo for a a press-release
type ContactInfo struct {
Persons []*Person `json:"persons" bson:"persons"` // definition of Persons omitted for conciseness
ContactData string `json:"contact_data" bson:"contact_data"`
}
// PressRelease is a document in MongoDB
type PressRelease struct {
ID bson.ObjectId `json:"_id" bson:"_id"`
*ContactInfo
*Content
}
我想检索一个PressRelease
,所以在另一个包中,我有:
type mongoClient struct {
*mgo.Collection
// other irrelevant stuff...
}
func (mc mongoClient) ListRecentUnhandled(c context.Context) (*api.PressRelease, error) {
var pr api.PressRelease
err := mc.Find(nil).Sort("-timestamp").One(&pr)
return &pr, err
}
以上ListRecentUnhandled
仅填充api.PressRelease.ID
。嵌套结构api.Content
和api.ContactInfo
的值仍为nil
。
我首先尝试构建一个可执行的测试用例。但是,我无法在Go操场中重现此行为:https://play.golang.org/p/p0pyuJEwGRJ
结果:无法重现
然后我尝试通过将mgo
驱动程序反序列化来检查map[struct]interface{}
驱动程序返回的数据。结果如预期。我找到的钥匙是:
结果:所有键值都存在并被占用,结果中不包含多余数据
spew.Dump
验证密钥和值类型。我希望交叉验证来自map[string]interface{}
的结果,以确保我没有忽略任何内容,因此我安装了https://github.com/davecgh/go-spew/spew和spew.Dump
ed返回的数据。以下是结果:
(map[string]interface {}) (len=8) {
(string) (len=11) "description": (string) (len=4402) "[…]",
(string) (len=12) "contact_data": (string) (len=107) "[…]",
(string) (len=6) "sector": (string) (len=8) "sciences",
(string) (len=3) "_id": (bson.ObjectId) (len=12) ObjectIdHex("5ab52ec79af937109ee5ad3c"),
(string) (len=9) "timestamp": (time.Time) 2018-03-23 16:43:51.56 +0000 UTC,
(string) (len=8) "pub_date": (time.Time) 2016-06-06 17:54:51 +0000 UTC,
(string) (len=7) "persons": ([]interface {}) {},
(string) (len=5) "title": (string) (len=138) "[…]"
}
我尝试替换var pr api.PressRelease
?使用api.Content
和api.ContactInfo
。两个结构都是单独填充的,没有问题。
结果:数据有效,可以单独反序列化为组成结构
func (mc mongoClient) ListRecentUnhandled(c context.Context) (*api.PressRelease, error) {
var pr api.PressRelease
pr.Content = new(api.Content)
pr.ContactInfo = new(api.ContactInfo)
err := mc.Find(nil).Sort("-timestamp").One(&pr)
return &pr, err
}
结果:与之前相同(仅填充ID字段)
这里发生了什么?
如何将mgo
查询反序列化为嵌入式结构?