在Go语言结合mgo驱动操作MongoDB的开发场景中,我们经常会定义包含嵌入式结构体的数据模型,默认情况下嵌入式结构体的字段会被存储为父文档下的子文档,而bson:",inline"标签可以让这些字段直接平铺到父文档中,实现扁平化存储。

bson:",inline"标签的基本作用
bson:",inline"是mgo驱动支持的BSON标签选项,当将其添加到嵌入式结构体的字段标签中时,序列化该结构体到BSON文档时,嵌入式结构体的所有字段会被直接合并到父结构体的BSON文档中,不会生成额外的嵌套层级。
默认存储与扁平化存储的对比
我们先定义两个结构体,一个包含嵌入式结构体但不添加inline标签,一个添加inline标签,观察两者的存储差异。
默认存储示例
首先定义基础结构体和包含嵌入结构体的父结构体:
package main
import (
"fmt"
"gopkg.in/mgo.v2/bson"
)
// 嵌入式结构体
type Address struct {
City string `bson:"city"`
Street string `bson:"street"`
}
// 默认嵌入的父结构体
type UserDefault struct {
Name string `bson:"name"`
Age int `bson:"age"`
Address Address `bson:"address"` // 没有添加inline标签
}
将上述结构体实例序列化为BSON再转成可读的map查看结果:
func main() {
user := UserDefault{
Name: "张三",
Age: 20,
Address: Address{
City: "北京",
Street: "长安街",
},
}
bsonData, err := bson.Marshal(user)
if err != nil {
fmt.Println("序列化失败:", err)
return
}
var result map[string]interface{}
bson.Unmarshal(bsonData, &result)
fmt.Println("默认存储结果:", result)
}
运行后输出的结果如下,Address的字段被嵌套在address子文档中:
默认存储结果: map[name:张三 age:20 address:map[city:北京 street:长安街]]
添加inline标签后的扁平化存储
修改父结构体,给Address字段添加bson:",inline"标签:
// 添加inline标签的父结构体
type UserInline struct {
Name string `bson:"name"`
Age int `bson:"age"`
Address Address `bson:"inline"` // 添加inline标签
}
同样进行序列化操作:
func main() {
user := UserInline{
Name: "张三",
Age: 20,
Address: Address{
City: "北京",
Street: "长安街",
},
}
bsonData, err := bson.Marshal(user)
if err != nil {
fmt.Println("序列化失败:", err)
return
}
var result map[string]interface{}
bson.Unmarshal(bsonData, &result)
fmt.Println("扁平化存储结果:", result)
}
运行后输出的结果中,City和Street字段直接平铺在父文档中,没有嵌套的address子文档:
扁平化存储结果: map[name:张三 age:20 city:北京 street:长安街]
使用注意事项
- 如果嵌入式结构体和父结构体存在同名字段,添加inline标签后会导致字段覆盖,需要提前避免字段名冲突。
- inline标签仅对BSON序列化生效,不会影响结构体本身的JSON等其他序列化方式,如果需要JSON也扁平化需要单独配置JSON标签。
- 该标签适用于需要简化MongoDB文档结构、减少查询时嵌套层级的场景,比如地址、基础配置类信息嵌入到主文档中。
实际业务场景示例
假设我们有一个订单结构体,需要嵌入支付信息,并且希望支付字段直接存在订单文档中,就可以使用inline标签:
package main
import (
"fmt"
"gopkg.in/mgo.v2/bson"
)
type Payment struct {
PayType string `bson:"pay_type"`
PayTime int64 `bson:"pay_time"`
Amount float64 `bson:"amount"`
}
type Order struct {
OrderID string `bson:"order_id"`
UserID string `bson:"user_id"`
Payment Payment `bson:"inline"` // 支付字段扁平化
}
func main() {
order := Order{
OrderID: "ORD123456",
UserID: "UID789",
Payment: Payment{
PayType: "微信支付",
PayTime: 1690000000,
Amount: 199.9,
},
}
bsonData, _ := bson.Marshal(order)
var result map[string]interface{}
bson.Unmarshal(bsonData, &result)
fmt.Println("订单存储结果:", result)
}
上述代码运行后,支付相关的字段会直接出现在订单文档中,方便后续直接查询订单时获取支付信息,不需要额外解析嵌套子文档。
Gomgobson_inline嵌入式结构体扁平化存储修改时间:2026-07-13 08:09:24