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!