Home > Blockchain >  Problem with FindOne using mongo-driver/mongo in Golang
Problem with FindOne using mongo-driver/mongo in Golang

Time:09-22

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)
  • Related