处理自定义 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,并防止您有额外的结构使事情变得混乱。


慕码人8056858
浏览 155回答 1
1回答

呼唤远方

自定义 bson 编组/解组的工作方式几乎相同,您必须分别实现Getter和Setter接口这样的事情应该工作: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    }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go