json - 处理自定义 BSON 编码

标签 json mongodb go bson

我有许多需要自定义编码的结构。当我测试时,我使用的是 JSON 和标准的 JSON 编码器。由于它不会编码未导出的字段,因此我需要编写一个自定义 MarshalJSON 函数,该函数运行良好。当我在包含需要自定义编码作为字段的父结构上调用 json.Marshal 时,它工作正常。

现在我需要将所有内容编码到 BSON 以进行一些 MongoDB 工作,但我找不到任何有关如何编写自定义 BSON 编码的文档。谁能告诉我如何为 BSON/mgo 做同样的事情,就像我在下面演示的那样?

currency.go(重要部分)

type Currency struct {
    value        decimal.Decimal //The actual value of the currency.
    currencyCode string          //The ISO currency code.
}

/*
MarshalJSON implements json.Marshaller.
*/
func (c Currency) MarshalJSON() ([]byte, error) {
    f, _ := c.Value().Float64()
    return json.Marshal(struct {
        Value        float64 `json:"value" bson:"value"`
        CurrencyCode string  `json:"currencyCode" bson:"currencyCode"`
    }{
        Value:        f,
        CurrencyCode: c.CurrencyCode(),
    })
}

/*
UnmarshalJSON implements json.Unmarshaller.
*/
func (c *Currency) UnmarshalJSON(b []byte) error {

    decoded := new(struct {
        Value        float64 `json:"value" bson:"value"`
        CurrencyCode string  `json:"currencyCode" bson:"currencyCode"`
    })

    jsonErr := json.Unmarshal(b, decoded)

    if jsonErr == nil {
        c.value = decimal.NewFromFloat(decoded.Value)
        c.currencyCode = decoded.CurrencyCode
        return nil
    } else {
        return jsonErr
    }
}

product.go(同样,只是相关部分)

type Product struct {
    Name  string
    Code  string
    Price currency.Currency
}

当我调用 json.Marshal(p) 其中 p 是一个产品时,它会产生我想要的输出,而不需要你创建一个结构的模式(不确定名称),它只是一个克隆,所有导出字段。

在我看来,使用我使用过的内联方法可以大大简化 API,并且不会有额外的结构来使事情变得困惑。

最佳答案

自定义 bson Marshalling/Unmarshalling 的工作方式几乎相同,您必须实现 GetterSetter接口(interface)分别

这样的事情应该可以工作:

type Currency struct {
    value        decimal.Decimal //The actual value of the currency.
    currencyCode string          //The ISO currency code.
}

// GetBSON implements bson.Getter.
func (c Currency) GetBSON() (interface{}, error) {
    f := c.Value().Float64()
    return struct {
        Value        float64 `json:"value" bson:"value"`
        CurrencyCode string  `json:"currencyCode" bson:"currencyCode"`
    }{
        Value:        f,
        CurrencyCode: c.currencyCode,
    }, nil
}

// SetBSON implements bson.Setter.
func (c *Currency) SetBSON(raw bson.Raw) error {

    decoded := new(struct {
        Value        float64 `json:"value" bson:"value"`
        CurrencyCode string  `json:"currencyCode" bson:"currencyCode"`
    })

    bsonErr := raw.Unmarshal(decoded)

    if bsonErr == nil {
        c.value = decimal.NewFromFloat(decoded.Value)
        c.currencyCode = decoded.CurrencyCode
        return nil
    } else {
        return bsonErr
    }
}

关于json - 处理自定义 BSON 编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30891301/

相关文章:

go - GO 中的包/函数中毒

javascript - POST 错误 500(内部服务器错误)- JSON 语法错误

multithreading - 为什么我的多线程插件比单线程插件性能更好?

android - 如何使用 Android 通过 HttpClient 请求发送 JSON 对象?

mongodb - 索引对Mongo按位查询有帮助吗

javascript - MongoDB 安全性,我缺少什么?

go - 我无法在Go中的 slice 中更改struct变量的值

go - 如何获取 strings.Contains 中的结果数?

java - jsonp.java.net : how to build with maven

javascript - Angular 2 : How to display image to HTML from JSON API