处理定制BSON Marshaling(Golang& mgo) [英] Handling Custom BSON Marshaling (Golang & mgo)

查看:155
本文介绍了处理定制BSON Marshaling(Golang& mgo)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些需要自定义编组的结构。当我测试时,我使用JSON和标准的JSON编组器。由于它不编码未导出的字段,因此我需要编写一个自定义的MarshalJSON函数,该函数完美运行。当我在包含那些需要自定义编组的字段的父结构体上调用json.Marshal时,它运行正常。

I have a number of structs that require custom marshalling. When I was testing I was using JSON and the standard JSON marshaller. As it doesn't marshal unexported fields, I needed to write a custom MarshalJSON function, which worked perfectly. When I called json.Marshal on the parent struct containing the ones that needed custom marshalling as fields, it worked fine.

现在我需要为一些MongoDB编组一切到BSON工作,而且我找不到有关如何编写自定义BSON编组的任何文档。任何人都可以告诉我如何为我在下面演示的BSON / mgo做同样的事情?

Now I need to marshal everything to BSON for some MongoDB work, and I can't find any documentation about how to write custom BSON marshalling. Can anyone tell me how to do the equivalent for BSON/mgo for what I've demonstrated below?

currency.go (重要部分)

currency.go (the important parts)

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 (同样,只是相关的部分)

product.go (again, just the relevant parts)

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

当我调用json.Marshal(p),其中p是一个Product时,它会生成我想要的输出,而不需要该模式(不确定名称)在哪里创建一个结构,它只是一个包含所有导出在我看来,使用我使用的内联方法大大简化了API,并且阻止了额外的结构混乱。

When I call json.Marshal(p) where p is a Product, it produces the output I want without the need for the pattern (not sure of the name) where you create a struct which is just a clone with all exported fields.

$ b

推荐答案

自定义bson编组/解组以几乎相同的方式工作,您必须实施 Getter Setter 接口

Custom bson Marshalling/Unmarshalling works nearly the same way, you have to implement the Getter and Setter interfaces respectively

类似这样的东西应该可以工作:

Something like this should work :

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,
    }
}

// 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
    }
}

这篇关于处理定制BSON Marshaling(Golang& mgo)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆