'How to get ObjectID as String from mongo-go-driver cursor?
I would like to get ObjectID as a string because I have other storage types, so I want to avoid to use primitive.ObjectID in my struct to keep the layers independent. I'm new to Golang, thanks.
package listing
type Card struct {
ID string
Hanzi string
Pinyin string
Traducao string
}
My storage file: package storage
func (m *Mongodb)GetCards() []*listing.Card {
var list []*listing.Card
collection := m.Client.Database("flashcards").Collection("cards")
cur, err := collection.Find(context.TODO(), bson.M{})
if err != nil {
log.Fatal("Erro buscando cards:", err)
}
for cur.Next(context.TODO()) {
var card listing.Card
err = cur.Decode(&card)
if err != nil {
log.Fatal("Erro decodificando documento", err)
}
list = append(list, &card)
}
return list
}
Solution 1:[1]
As you, I was looking for a solution to keep modules as independent as possible and keep low coupling level. I scratched my head A LOT, but at the end I find this, I hope valid and clear, solution.
You can use a custom type which implement the ValueMarshaler interface: so you have to implement MarshalValue func!
type Card struct {
ID MyObjectID `bson:"_id"`
CardSuit string `bson:"cardSuit"`
}
type MyObjectID string
func (id MyObjectID) MarshalBSONValue() (bsontype.Type, []byte, error) {
p, err := primitive.ObjectIDFromHex(string(id))
if err != nil {
return bsontype.Null, nil, err
}
return bson.MarshalValue(p)
}
ID is pratically a string, but with the custom marshaller it will be saved as an ObjectID in Mongo, and parsed correctly when unmarshalling.
Here a working example, you need mongo obviously to make it run.
Solution 2:[2]
Ok, I figured out. I created another struct just to hold the ObjectId
type HexId struct {
ID primitive.ObjectID `bson:"_id"`
}
then I used Hex() to pass the value to Card.ID
err = cur.Decode(&card)
err = cur.Decode(&hexId)
card.ID = hexId.ID.Hex()
Now I can use it to make links.
Solution 3:[3]
For me it works out of the box when having the bson annotation (version 5.0.6):
type User struct {
Id string `bson:"_id,omitempty" json:"id,omitempty"`
Name string `bson:"name" json:"name"`
}
Solution 4:[4]
Use bson:"-" for ignore ObjectID in response and json:"-" for ignoring in database.
And you don't need to decode two times.
type Card struct {
ObjectID primitive.ObjectID `json:"-" bson:"_id"`
ID string `bson:"-"`
Hanzi string
Pinyin string
Traducao string
}
err = cur.Decode(&card)
card.ID = card.ObjectID.Hex()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Cirelli94 |
| Solution 2 | Bruno Canongia |
| Solution 3 | zim |
| Solution 4 |
