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

Golang存储数据到MongoDB时出现空值问题排查求助

Golang:API JSON转结构体存入MongoDB全为默认值的排查与解决

问题核心原因

  1. JSON反序列化结构不匹配
    API返回的是map[string]Currency格式(每个键对应一个完整的Currency对象),但你用map[string]Rate接收。Rate结构体中嵌入的Currency字段带有json:"currency"标签,意味着反序列化时会去寻找名为currency的子字段,但API返回的每个对象直接是Currency的平级字段,没有嵌套在currency下,导致Currency的所有字段无法被赋值,只能使用默认值。

  2. MongoDB序列化标签缺失
    Currency结构体未定义bson标签,存入Mongo时字段名会被自动转为小写蛇形(如AlphaCode变成alphacode),虽然这不是默认值问题的直接原因,但会导致存储的字段名不符合预期。

解决步骤与代码修改

1. 修正结构体定义(model.go)

根据需求选择两种方案之一:

方案A:保留Mongo中的currency嵌套结构

type Currency struct {
    Code        string  `json:"code" bson:"code"`
    AlphaCode   string  `json:"alphaCode" bson:"alphaCode"`
    NumericCode string  `json:"numericCode" bson:"numericCode"`
    Name        string  `json:"name" bson:"name"`
    Rate        float64 `json:"rate" bson:"rate"`
    Date        string  `json:"date" bson:"date"`
    InverseRate float64 `json:"inverseRate" bson:"inverseRate"`
}

type Rate struct {
    ID        primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
    Currency  Currency           `json:"currency" bson:"currency"` // 改为显式结构体字段,而非嵌入
    Timestamp primitive.DateTime `json:"timestamp" bson:"timestamp"`
}

方案B:将Currency字段直接嵌入Mongo文档(无嵌套)

type Currency struct {
    Code        string  `json:"code" bson:"code"`
    AlphaCode   string  `json:"alphaCode" bson:"alphaCode"`
    NumericCode string  `json:"numericCode" bson:"numericCode"`
    Name        string  `json:"name" bson:"name"`
    Rate        float64 `json:"rate" bson:"rate"`
    Date        string  `json:"date" bson:"date"`
    InverseRate float64 `json:"inverseRate" bson:"inverseRate"`
}

type Rate struct {
    ID        primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
    Currency  `bson:",inline"` // 用inline标签让Currency字段直接嵌入
    Timestamp primitive.DateTime `json:"timestamp" bson:"timestamp"`
}

2. 修正API数据反序列化逻辑

无论选择哪种方案,都需要先将API返回的JSON反序列化为map[string]Currency,再转换为map[string]Rate:

const apiUrl = "https://www.floatrates.com/daily/aud.json" 
func GetRatesFromAPI() (map[string]models.Rate, error) {
    response, err := http.Get(apiUrl)
    if err != nil {
        return nil, err
    }
    defer response.Body.Close()

    body, err := ioutil.ReadAll(response.Body)
    if err != nil {
        return nil, err
    }

    // 先匹配API结构,反序列化为map[string]Currency
    var currencyMap map[string]models.Currency
    if err := json.Unmarshal(body, &currencyMap); err != nil {
        return nil, err
    }

    // 转换为需要的Rate结构
    rateMap := make(map[string]models.Rate, len(currencyMap))
    for key, curr := range currencyMap {
        rateMap[key] = models.Rate{
            Currency: curr, // 方案A的赋值方式;方案B同样适用
        }
    }

    return rateMap, nil
}

3. 调试验证建议

  • 反序列化后打印currencyMap,确认API返回的数据是否被正确解析
  • 转换为rateMap后打印单个Rate对象,检查Currency字段是否有有效值
  • 存入Mongo前打印最终要插入的Rate对象,确保数据正确

内容的提问来源于stack exchange,提问作者Piter Penn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 04:37:11