首页 > 解决方案 > Go Mongo Driver 检索无模式文档

问题描述

在使用 Mongo Go 驱动程序时,我想检索无模式文档。

我可以使用检索文档但是当我尝试解码到结构时,bson.M json:",inline" bson:",inline" 这会在 json 中添加额外的“M”键

type Product struct {
    ID        primitive.ObjectID `bson:"_id"`
    ProductId string `bson:"product_id" json:"product_id"`
    bson.M `json:",inline" bson:",inline"`
}

输出:-

{
 "id":"<ObjectId>",
 "M":{
    "some":""
  }
}

但相反,我想要它如何存储在 Mongo 中。

{
  "id":"<ObjectId>",
  "some":""
}

我不能直接使用这样的东西,因为我想将它转换为 struct 以使用某些属性

var pr bson.M
err := p.FindOne(ctx, &p.options,query, &pr)

如何删除从 Mongo 转换无模式文档时添加的额外密钥?

我需要显式覆盖 MarshalJSON() 还是使用标签提供了一些东西?

标签: mongodbgo

解决方案


如何删除从 Mongo 转换无模式文档时添加的额外密钥?

您可以只定义一个字段映射名称,在编组时将其展平。例如:

type Product struct {
    ID          primitive.ObjectID      `bson:"_id"`
    ProductId   string                  `bson:"product_id"`
    Others      bson.M                  `bson:",inline"`
}

当您解码一个文档时,您会看到它将包含其他没有Others名称的字段。例如,如果您有一个文档:

{
 "_id": ObjectId("5e8d330de85566f5a0557ea4"), 
 "product_id": "foo", 
 "some": "x", 
 "more": "y"
}
doc := Product{}
err = cur.Decode(&doc)
fmt.Println(doc)
// Outputs 
// {ObjectID("5e8d330de85566f5a0557ea4") foo map[more:y some:x]}

我不能直接使用这样的东西,因为我想将它转换为 struct 以使用某些属性

您可以直接将其用于查询谓词。例如:

// After decoding 'doc' to product
var result bson.M
err := collection.FindOne(context.TODO(), doc).Decode(&result)

使用MongoDB Go 驱动程序v1.3.2测试

更新:

如果你想返回 JSON,你可以使用bson.MarshalExtJSON()。在处理 JSON 中不存在的对象方面,这也应该更容易。即ObjectId。例如:

// After decoding 'doc' to product
ejson, err := bson.MarshalExtJSON(doc, true, false)
fmt.Println(string(ejson)) 

推荐阅读