Struggling with unmarshalling data in Golang from mongo, may be cause I am new to this. Just started learning golang with MongoDB
Tried with map[string]interface{} to avoid any struct related errors
var data map[string]interface{}
filter := bson.M{"profile.username": username}
singleResult := u.getCollection(client).FindOne(u.ctx, filter)
err := singleResult.Decode(data)
This fails to unmarshall with error cannot Decode to nil value
Tried with exact struct structure too.
var result *models.UserData
filter := bson.M{"profile.username": username}
singleResult := u.getCollection(client).FindOne(u.ctx, filter)
err := singleResult.Decode(result)
Fails with same error cannot Decode to nil value
Tried to find all with map[string]interface{}
var result []models.UserData
cursor, _ := u.getCollection(client).Find(u.ctx, bson.M{})
err := cursor.All(u.ctx, &result)
Works perfectly as expected
Tried to find all with exact struct structure
var data []map[string]interface{}
cursor, _ := u.getCollection(client).Find(u.ctx, bson.M{})
err := cursor.All(u.ctx, &result)
Works perfectly as expected
Now I thought may be I am not finding the data in mongo but then
filter := bson.M{"profile.username": username}
singleResult := u.getCollection(client).FindOne(u.ctx, filter)
raw, _ := singleResult.DecodeBytes()
log.Print("\n\n" raw.String() "\n\n")
This prints the data as expected. Although one thing I noticed all non-string values are formatted as {"$numberLong":"1"}
. Still don't know if it is correct or cause of the issue.
CodePudding user response:
In your first 2 examples that fail, the data passed to Decode()
are both nil
:
// data == nil
var data map[string]interface{}
// ...
// result == nil
var result *models.UserData
Try like
var result = &models.UserData{} // init the pointer with a block of valid allocated memory
// ...
err := singleResult.Decode(result)
CodePudding user response:
In order for Decode()
to write the document(s) into the passed value, it must be a (non-nil
) pointer. Passing any value creates a copy, and if you pass a non-pointer, only the copy could be modified. If you pass a pointer, a copy is still made, but Decode()
will modify the pointed value, not the pointer.
In your first 2 examples that fail, you pass a non-pointer (or a nil
pointer):
err := singleResult.Decode(result)
Modify it to pass a (non-nil
) pointer:
err := singleResult.Decode(&result)
Your last 2 examples work because you're already passing (non-nil
) pointers:
err := cursor.All(u.ctx, &result)