
本文介绍使用 go(基于 mgo 驱动)将字符串格式的 json 数组解析为多个文档,并高效批量写入 mongodb 的完整流程,涵盖反序列化、类型处理、错误防范及实际插入操作。
本文介绍使用 go(基于 mgo 驱动)将字符串格式的 json 数组解析为多个文档,并高效批量写入 mongodb 的完整流程,涵盖反序列化、类型处理、错误防范及实际插入操作。
在 Go 应用中,常需将前端或外部服务传来的 JSON 数组(如 [{"key1":1,"key2":"val2"}, ...])作为多条独立记录存入 MongoDB。关键在于:不能将整个 JSON 数组作为一个文档插入,而应将其解包为多个 BSON 文档并批量写入。
步骤解析
-
JSON 反序列化为 Go 切片
使用 json.Unmarshal 将原始 JSON 字符串([]byte)解析为 []interface{}。该类型可适配任意结构的 JSON 对象数组,且能被 mgo 自动转换为 BSON 文档:
var docs []interface{}
if err := json.Unmarshal(jsonBytes, &docs); err != nil {
log.Fatal("JSON 解析失败:", err)
}✅ 注意:[]interface{} 是通用容器,适用于未知结构的 JSON;若结构固定,推荐定义具体 struct 类型以获得编译期检查和更好性能。
-
批量插入到 MongoDB
调用 Collection.Insert() 并使用展开操作符 ... 将切片元素作为独立参数传入,mgo 会为每个 interface{} 元素生成一条文档:
session := session.Copy()
defer session.Close()
c := session.DB("mydb").C("mycollection")
if err := c.Insert(docs...); err != nil {
log.Fatal("MongoDB 插入失败:", err)
}-
增强健壮性的建议实践
- ✅ 显式管理会话生命周期:避免连接泄漏,务必调用 session.Copy() 和 defer session.Close()。
- ✅ 校验数组长度:空数组调用 Insert(...) 会静默跳过,建议前置判断 len(docs) == 0 并按需处理。
- ⚠️ 注意 ObjectId 生成:mgo 默认为无 _id 字段的文档自动生成 ObjectId;若 JSON 中已含 _id(如字符串格式),需确保其符合 ObjectId 格式,否则插入可能失败或被忽略。必要时可预处理:
for i := range docs { if m, ok := docs[i].(map[string]interface{}); ok { if id, exists := m["_id"]; exists && reflect.TypeOf(id).Kind() == reflect.String { if oid, err := bson.ObjectIdHex(id.(string)); err == nil { m["_id"] = oid } } } }
完整示例代码
package main
import (
"encoding/json"
"log"
"reflect"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
func insertJSONArrToMongo(jsonStr string, session *mgo.Session, dbName, collName string) error {
var docs []interface{}
if err := json.Unmarshal([]byte(jsonStr), &docs); err != nil {
return err
}
if len(docs) == 0 {
return nil // 无数据,直接返回
}
c := session.DB(dbName).C(collName)
return c.Insert(docs...)
}
// 使用示例
func main() {
jsonInput := `[{"key1":1,"key2":"val2"},{"key1":2,"key2":"val2"}]`
session, err := mgo.Dial("mongodb://localhost:27017")
if err != nil {
log.Fatal(err)
}
defer session.Close()
if err := insertJSONArrToMongo(jsonInput, session, "testdb", "testcoll"); err != nil {
log.Fatal("插入失败:", err)
}
log.Println("✅ 批量插入成功,共", len([]byte(jsonInput)), "字节 JSON 数据")
}? 提示:现代项目推荐迁移到官方驱动 go.mongodb.org/mongo-driver/mongo,其 InsertMany 方法语义更清晰、上下文支持更完善;但 mgo 在存量系统中仍广泛使用,本方案保持兼容性与实用性。
通过以上方式,即可安全、高效地将动态 JSON 数组转化为 MongoDB 中的多条独立记录。


















