go 使用 mgo 驱动保存结构体到 mongodb 时,若字段名首字母小写(未导出),驱动无法访问其值,导致仅插入空文档(仅有 `_id`)。解决方法是将结构体字段首字母大写,使其可导出,并推荐显式添加 bson 标签以精确控制字段映射。
在 Go 语言中,结构体字段的可见性由首字母大小写决定:只有首字母大写的字段才是“导出的”(exported),才能被其他包(如 mgo)通过反射机制读取和序列化。而原始代码中定义的 Result 结构体所有字段均为小写开头(如 nid, timestamp),属于非导出字段,mgo 在执行 Insert() 时无法获取其值,因此只生成了带 _id 的空文档。
✅ 正确做法是:
修正后的结构体如下:
type Result struct {
Nid string `bson:"nid" json:"nid"`
Timestamp int64 `bson:"timestamp" json:"timestamp"`
Hexhash string `bson:"hexhash" json:"hexhash"`
Addr string `bson:"addr" json:"addr"`
}创建并插入实例时保持不变:
r := Result{
Nid: hex_id,
Timestamp: int64(msg.timestamp.Unix()),
Hexhash: hexhash,
Addr:
msg.addr.String(),
}
fmt.Printf("Inserting: %+v\n", r) // 调试确认值已正确赋值
err := h.c.Insert(r)
if err != nil {
log.Fatal("Failed to insert:", err)
}⚠️ 注意事项:
总结:Go 的封装机制决定了 ORM/ODM 类库必须依赖导出字段。从设计之初就应遵循 Go 的导出规范——让结构体字段“看得见”,才能让数据真正“存得进”。