Golang从MongoDB返回全部历史记录异常:仅返回最后一条数据
问题分析与修复
你的代码存在几个关键问题,导致接口仅返回最后一条记录:
- 返回对象错误:最终返回的是单个
bson.D类型的results,而非存储所有记录的切片resultsSlice。循环中每次解码都会覆盖results的值,最后自然只剩最后一条数据。 - 切片追加逻辑错误:
resultsSlice = append(resultsSlice, results)仅在Decode出错的分支执行,正常解码时根本没往切片中添加数据。 - 错误处理混乱:
Decode出错后调用cursor.All毫无意义,且log.Fatal会直接终止程序,应将错误返回给上层而非直接崩溃。 - 注释中的
cursor.All用法错误:cursor.All需要传入切片指针,而非单个bson.D的指针,所以之前注释的代码会返回空值。
修复方案(两种可选)
方案一:使用cursor.All(推荐,更简洁)
直接用cursor.All一次性将所有结果解码到切片中,无需手动循环:
func (h History) GetAll(ctx context.Context) (interface{}, error) { coll := collection() cursor, err := coll.Find(ctx, bson.D{}) if err != nil { return nil, err // 返回错误而非直接终止程序 } defer cursor.Close(ctx) var resultsSlice []bson.D // 传入切片指针,一次性解码所有结果 if err = cursor.All(ctx, &resultsSlice); err != nil { return nil, err } return resultsSlice, nil }
方案二:手动循环解码
如果需要逐行处理记录,修正循环逻辑,每次解码到新变量并追加到切片:
func (h History) GetAll(ctx context.Context) (interface{}, error) { coll := collection() cursor, err := coll.Find(ctx, bson.D{}) if err != nil { return nil, err } defer cursor.Close(ctx) var resultsSlice []bson.D for cursor.Next(ctx) { var result bson.D // 每次循环创建新变量,避免覆盖之前的数据 if err = cursor.Decode(&result); err != nil { return nil, err // 返回错误给调用方 } resultsSlice = append(resultsSlice, result) // 正常解码后追加到切片 fmt.Println(result) } // 检查游标遍历过程中是否出现错误 if err = cursor.Err(); err != nil { return nil, err } return resultsSlice, nil }
关键修正点总结
- 确保返回存储所有记录的切片,而非单个对象
- 循环解码时每次使用新变量,避免覆盖已有数据
- 正确处理错误:将错误返回给调用方,而非直接终止程序
- 使用
cursor.All时传入切片指针,而非单个对象指针
内容的提问来源于stack exchange,提问作者Buluc-Chabtan
相关产品推荐
相关产品推荐

