json - Golang bson structs - 对 json 中的单个字段使用多个字段名称,但只有一个用于写入数据库

标签 json mongodb go struct bson

我有一个这样的结构-

type Address struct {
    AddressLine1 string        `json:"addressLine1" bson:"addressLine1"`
    AddressLine2 string        `json:"addressLine2" bson:"addressLine2"`
    Landmark     string        `json:"landmark" bson:"landmark"`
    Zipcode      string        `json:"zipcode" bson:"zipcode"`
    City         string        `json:"city" bson:"city"`
}

由于以前的版本和最新的尚未发布的版本之间存在一些兼容性问题,我想确保如果有人发布使用此结构解码的 json 数据,他们应该能够使用“zipcode”或 'pincode' 作为其 json 中的字段名称。但是当这个值被写入我的数据库时,字段名称应该只是'zipcode'。

简而言之,

{
"city": "Mumbai",
"zipcode": "400001"
}

{
"city": "Mumbai",
"pincode": "400001"
}

都应该在数据库中显示为 -

{
"city": "Mumbai",
"zipcode": "400001"
}

我如何允许这样做?

最佳答案

您可以将两个字段都作为指向字符串的指针:

type Address struct {
    AddressLine1 string        `json:"addressLine1" bson:"addressLine1"`
    AddressLine2 string        `json:"addressLine2" bson:"addressLine2"`
    Landmark     string        `json:"landmark" bson:"landmark"`
    Zipcode      *string       `json:"zipcode,omitempty" bson:"zipcode"`
    Pincode      *string       `json:"pincode,omitempty" bson:"zipcode"`
    City         string        `json:"city" bson:"city"`
}

正如您可能注意到的,我们在 json 标记中使用了 omitempty,因此如果其中一个字段不存在于 json 中,它将被忽略为 nil指针,它不会出现在 Marshal()Unmarshal()

之后

编辑:

在这种情况下,我们所要做的就是实现方法 UnmarshalJSON([]byte) error 来满足接口(interface) Unmarshaler ,方法 json.Unmarshal() 将始终尝试调用该方法,我们可以在 Unmarshal 结构之后添加我们自己的逻辑,在这种情况下我们想知道是否 pincode如果我们将其分配给 zipcode 则已解决: 完整示例在这里:https://play.golang.org/p/zAOPMtCwBs

type Address struct {
    AddressLine1 string  `json:"addressLine1" bson:"addressLine1"`
    AddressLine2 string  `json:"addressLine2" bson:"addressLine2"`
    Landmark     string  `json:"landmark" bson:"landmark"`
    Zipcode      *string `json:"zipcode,omitempty" bson:"zipcode"`
    Pincode      *string `json:"pincode,omitempty"`
    City         string  `json:"city" bson:"city"`
}

// private alias of Address to avoid recursion in UnmarshalJSON()
type address Address

func (a *Address) UnmarshalJSON(data []byte) error {
    b := address{}
    if err := json.Unmarshal(data, &b); err != nil {
        return nil
    }
    *a = Address(b) // convert the alias to address

    if a.Pincode != nil && a.Zipcode == nil {
        a.Zipcode = a.Pincode
        a.Pincode = nil // unset pincode
    }

    return nil
}

注意 Zipcode 字段有一个 bson 标签而 Pincode 没有,我们还必须创建一个地址类型的别名以避免递归调用 UnmarshalJSON

关于json - Golang bson structs - 对 json 中的单个字段使用多个字段名称,但只有一个用于写入数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39992260/

相关文章:

windows - Go程序访问线程环境 block 时出现panic

jquery - 戈朗 : Extracting XML Issue

go - 为什么 os/exec.CombinedOutput() 没有竞争条件?

javascript - 如何访问ag-grid表数据和详细信息的嵌套对象数组值?

ios - 将 JSON 数组反序列化为对象的 Swift 数组

json - 从空接口(interface)检索值

mongodb - 查找给定的经纬度是否位于 MongoDB 中的任何多边形中

json - 如何在 Django 中使用 PostgreSQL 9.2 JSON 数据类型?

javascript - 在nodejs中一段时间​​后挂断http连接

mongodb - ReactiveMongo 0.9 : Joda Datetime Implicit Conversion for Macros. 处理程序