Go语言读取CSV变量批量插入MongoDB问题求助
修正后的Go代码及问题解析
代码中的关键错误点
- 类型定义不能放在循环代码块内,需移至函数外部或包级别
- 结构体字段未导出(首字母小写),MongoDB驱动无法识别,需改为大写开头
- 结构体标签格式错误,引号转义错误且bson标签类型声明有误
- CSV读取结果赋值语法错误,
{}string reader是无效写法,需取对应列的字符串值 - 缺少InsertOne调用后的错误检查,直接panic会导致程序终止,鲁棒性差
完整可运行代码示例
package main import ( "encoding/csv" "io" "log" "os" "time" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) // 定义在包级别,字段首字母大写以导出,确保MongoDB驱动能识别 type Event struct { EventID string `json:"event_id" bson:"event_id"` DateAdded time.Time `json:"date_added" bson:"date_added"` // 直接存time.Time类型,适配MongoDB的ISODate } func main() { // 初始化MongoDB客户端,根据实际连接地址调整 clientOpts := options.Client().ApplyURI("mongodb://localhost:27017") cli, err := mongo.Connect(nil, clientOpts) if err != nil { log.Fatal(err) } defer cli.Disconnect(nil) // 打开目标CSV文件 file, err := os.Open("your_file.csv") if err != nil { log.Fatal(err) } defer file.Close() csvreader := csv.NewReader(file) // 若CSV有表头,可取消注释跳过第一行 // _, err = csvreader.Read() // if err != nil { // log.Fatal(err) // } // 循环读取CSV行 for { record, err := csvreader.Read() if err == io.EOF { log.Println("CSV文件读取完成") break } if err != nil { log.Printf("读取CSV行失败: %v", err) continue // 出错时跳过当前行,继续处理后续内容 } // 检查行数据是否有效,假设event_id在CSV第一列 if len(record) < 1 { log.Println("无效的CSV行,列数不足") continue } // 构造Event实例 event := Event{ EventID: record[0], DateAdded: time.Now(), } // 插入到指定的MongoDB集合 result, err := cli.Database("your_db").Collection("your_collection").InsertOne(nil, event) if err != nil { log.Printf("插入MongoDB失败: %v", err) continue } log.Printf("成功插入文档,ID: %v", result.InsertedID) } }
关键说明
- 结构体字段导出:Go语言中只有首字母大写的字段才能被外部包(如MongoDB驱动)访问,所以字段名必须大写开头,同时通过
bson标签指定MongoDB集合中的字段名。 - 时间类型处理:直接使用
time.Time存储时间比字符串更合理,MongoDB会自动将其转为ISODate类型,方便后续的时间范围查询等操作。如果一定要存字符串,可将DateAdded改为string类型,赋值时用time.Now().Format("2006-01-02 15:04"),同时bson标签保持bson:"date_added"。 - 错误处理优化:替换
panic为日志打印并继续循环,避免单个行的错误导致整个程序终止,提升代码的鲁棒性。 - CSV读取校验:增加行数据长度检查,避免因空行或列数不足导致的索引越界错误。
内容的提问来源于stack exchange,提问作者Tun Aung
相关产品推荐
相关产品推荐

