为什么mongo不填充嵌入式结构?

时间:2018-03-23 19:19:26

标签: go mgo

我有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.Contentapi.ContactInfo的值仍为nil

以前的尝试/工作

可执行测试用例

我首先尝试构建一个可执行的测试用例。但是,我无法在Go操场中重现此行为:https://play.golang.org/p/p0pyuJEwGRJ

结果:无法重现

检查mgo

返回的数据内容

然后我尝试通过将mgo驱动程序反序列化来检查map[struct]interface{}驱动程序返回的数据。结果如预期。我找到的钥匙是:

  • 时间戳
  • PUB_DATE
  • 标题
  • 描述
  • contact_data
  • 扇区
  • _id

结果:所有键值都存在并被占用,结果中不包含多余数据

使用spew.Dump验证密钥和值类型。

我希望交叉验证来自map[string]interface{}的结果,以确保我没有忽略任何内容,因此我安装了https://github.com/davecgh/go-spew/spewspew.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.Contentapi.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查询反序列化为嵌入式结构?

0 个答案:

没有答案