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

如何使用 golang 检索 mongodb 中的嵌套对象数组?

如何使用 golang 检索 mongodb 中的嵌套对象数组?

Go
人到中年有点甜 2023-01-03 16:19:04
我正在使用 Golang/Fiber + Mongo 驱动程序。我有一个简单的博客文章结构:type Post struct {    ID          primitive.ObjectID `json:"_id" bson:"_id,omitempty"`    Title       *string            `json:"title" bson:"title"`    Slug        *string            `json:"slug" bson:"slug"`    Content     []interface{}      `json:"content" bson:"content,omitempty"` // same as any[]    CreatedAt   time.Time          `json:"created_at" bson:"created_at"`    UpdatedAt   time.Time          `json:"updated_at" bson:"updated_at"`    PublishedAt *time.Time         `json:"published_at" bson:"published_at"`}在内容中,我放置了对象数组:[    {        data: 'blah blah'    },    {        data: 'blah blah'    }]方法本身非常简单:func GetPostBySlug(slug string) (Post, error) {    post := Post{}    filter := bson.M{        "slug": slug,    }    database, error := Database.GetMongoDatabase()    if error != nil {        println(error)    }    collection := database.Collection(model_name)    err := collection.FindOne(ctx, filter).Decode(&post)    if err != nil {        return post, err    }    return post, nil}这就是我得到的:"_id": "000000000000000000000000","title": "Test","slug": "test","content": [ // array of arrays? what??    [        {            "Key": "data",            "Value": "blah blah"        },        {            "Key": "data",            "Value": "blah blah"        },    ]],"created_at": "2022-06-07T21:08:04.261Z","updated_at": "2022-07-20T21:42:36.717Z","published_at": null在 mongodb 中,内容字段完全按照我传递的方式保存,但是当我尝试获取文档时,内容会转换为这个带有键值对的奇怪数组。如果我保存如下内容:content: [    {        data: {            test: 'test',            what: 'what'        }    }]它将转换为:content: [    [        Key: "data",        Value: [            {                Key: "test",                Value: "test"             },            {                Key: "what",                Value: "what"             },        ]    ]]我理解这背后的原因(这只是 golang 处理 JSON 的方式?)并假设中间某处应该有一个额外的步骤,但我不知道我到底需要做什么
查看完整描述

3 回答

?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

修改类型Contentinterface{}或只是string



查看完整回答
反对 回复 2023-01-03
?
qq_花开花谢_0

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

您看到的原因是因为您使用interface{}的元素类型为Content:


Content []interface{}

如果使用interface{},它基本上不携带类型信息,驱动程序在对数组元素进行 umarshaling 时应该使用什么类型,因此驱动程序将选择/使用bson.D来表示content字段的文档。bson.D是一个切片,其中包含文档的有序字段列表,这就是为什么您会看到“数组的数组”。每个bson.D都是一个切片,代表一个文档。


type D []E


type E struct {

    Key   string

    Value interface{}

}

如果您可以使用结构对数组元素建模,请使用它,例如:


type Foo struct {

    Bar string

    Baz int

}


Content []Foo `json:"content" bson:"content,omitempty"`

// Or a pointer to Foo:

Content []*Foo `json:"content" bson:"content,omitempty"`

如果您没有数组元素的固定模型,或者您可以使用bson.Mwhich is a map(但是字段/属性将是无序的,这可能是也可能不是问题):


type M map[string]interface{}

使用它:


Content []bson.M `json:"content" bson:"content,omitempty"`


查看完整回答
反对 回复 2023-01-03
?
蝴蝶不菲

TA贡献1810条经验 获得超4个赞

只有 []bson.M 如果它是一个数组...我不得不使用 bson.M 而不是因为我的数据结构。



查看完整回答
反对 回复 2023-01-03
  • 3 回答
  • 0 关注
  • 137 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号