I am trying to figure out how to get a single subdocument from an array and unmarshal it into a struct.
My mongo document looks like this:
{
"_id" : ObjectId("abc123"),
"gamecode" : "abc123"
"players" : [
{
"playerid" : ObjectId("abc123"),
"username" : "test",
},
{
"playerid" : ObjectId("abc456"),
"username" : "test2"
}]
}
And I have a player struct that looks like this:
type Player struct {
PlayerID bson.ObjectId `bson:"playerid" json:"playerid"`
Username string `bson:"username" json:"username"`
}
From the mongo command line I can do a
db.games.find(({"players.playerid": ObjectId('abc123')}, {"_id": 0, "players.$":1})
Which returns
{"players" : [{ "playerid" : ObjectId("abc123"), "username" : "test"}]}
But I am having a hard time figuring out how to implement this same functionality in Go so that I have a populated player struct from the result of the query. I have been playing around with different configurations of the code below, but it always results in an empty struct. What am I missing here?
player := Player{}
collection.Find(bson.M{"players.playerid": bson.ObjectIdHex(pid)}).Select(bson.M{"_id": 0, "players.$": 1}).One(&player)
I am running the latest MongoDB version and am using the mgo.v2 driver for Go.
It's because you don't capture a single player, you capture players. like in the response from the mongo command:
{"players" : [{ "playerid" : ObjectId("abc123"), "username" : "test"}]}
Sounds like you can you an abstraction for a game
type Game struct {
Players []Player `bson:"players"`
}
And your call would be into &game
var game Game
collection.Find(bson.M{"...").One(&game)