Home >Backend Development >Golang >How to Implement Custom BSON Marshalling in Go for MongoDB?

How to Implement Custom BSON Marshalling in Go for MongoDB?

Linda Hamilton
Linda HamiltonOriginal
2024-12-04 11:30:12332browse

How to Implement Custom BSON Marshalling in Go for MongoDB?

Handling Custom BSON Marshalling in Go

When dealing with custom data structures in the context of MongoDB, it becomes necessary to implement custom marshaling and unmarshaling logic to ensure the correct representation and handling of data in BSON format. In this regard, Go provides interfaces like bson.Getter and bson.Setter, which allow custom marshaling and unmarshaling of specific data types.

Consider the following example, where a Currency struct is defined along with custom MarshalJSON and UnmarshalJSON methods to handle JSON encoding and decoding:

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

To achieve custom BSON marshaling, a similar approach can be used by implementing the bson.Getter and bson.Setter interfaces in the Currency struct:

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

By implementing these interfaces, the Currency struct now has custom BSON marshaling logic that maps its fields to the desired BSON representation, effectively handling custom data types in aMongoDB context.

The above is the detailed content of How to Implement Custom BSON Marshalling in Go for MongoDB?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn