ARTICLE AD BOX
I’m using MongoDB GoLang Driver v2 and I want to store a custom money type in MongoDB. If the value is nil, I want the BSON document to store price: null.
Example document I want:
{ "name": "Iphone", "price": null, "stock": 10 }My code:
import ( "fmt" money "github.com/Rhymond/go-money" "go.mongodb.org/mongo-driver/v2/bson" ) type moneyFields struct { Amount int64 `json:"amount" bson:"amount"` Currency string `json:"currency" bson:"currency"` } // Money wraps gomoney.Money for domain use type Money struct { // money.Money is of type: github.com/Rhymond/go-money money *money.Money } type Product struct { Name string `bson:"name"` Price *Money `bson:"price"` Stock int `bson:"stock"` }I implemented custom BSON marshaling:
func (m *Money) MarshalBSON() ([]byte, error) { // Handle nil pointer case - marshal as BSON null if m == nil { // I have tried all these and none work: return nil, nil // return bson.Marshal(nil) // return []byte{0x0A}, nil } doc := moneyFields{ Amount: m.money.Amount(), Currency: m.money.Currency().Code, } data, err := bson.Marshal(doc) if err != nil { return nil, fmt.Errorf("failed to marshal Money: %w", err) } return data, nil }The problem
When Price is nil, I get errors such as:
Unrecognized BSON type 110 in element ... mongo.MarshalError: bson.errNoEncoder {Type: reflect.Type nil}I also tried implementing:
func (m *Money) MarshalBSONValue() (bson.Type, []byte, error)But in MongoDB driver v2, this method never gets called, even though in v1 it does get called. Only MarshalBSON() is used.
My questions:
How do I correctly marshal a nil custom type as BSON null in MongoDB Go Driver v2?
Why does MarshalBSONValue never get called in v2?
What is the correct way to represent a nil custom struct pointer as BSON null in MongoDB v2?
I simply need:
*Money(nil) → BSON null
*Money{…} → BSON normal/embedded document
What is the correct way to do this in the v2 driver?
