You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang从MongoDB返回全部历史记录异常:仅返回最后一条数据

问题分析与修复

你的代码存在几个关键问题,导致接口仅返回最后一条记录:

  1. 返回对象错误:最终返回的是单个bson.D类型的results,而非存储所有记录的切片resultsSlice。循环中每次解码都会覆盖results的值,最后自然只剩最后一条数据。
  2. 切片追加逻辑错误:resultsSlice = append(resultsSlice, results)仅在Decode出错的分支执行,正常解码时根本没往切片中添加数据。
  3. 错误处理混乱:Decode出错后调用cursor.All毫无意义,且log.Fatal会直接终止程序,应将错误返回给上层而非直接崩溃。
  4. 注释中的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 23:57:20