how to get objects from document

58 views
Skip to first unread message

Poletaev Roman

unread,
Apr 6, 2016, 5:13:30 PM4/6/16
to mgo-users
type Room struct {
Name string `bson:"name"`
Code string `bson: "code`
}

type User struct {
ID bson.ObjectId `bson:"_id,omitempty"`
Name string `bson:"name"`
Rooms []Room `bson:"rooms`
}

how to get only Rooms from users collection?:
{
"_id": {
        "$oid": "56980d05282c61b7d98baa51"
    },
"rooms": [
{"name": "Test", "code": "AAA"},
{"name": "Test2", "code": "BBB"},
]
}

room := Room{}
db.collection("users").FindId(bson.ObjectIDHex("56980d05282c61b7d98baa51")).Select(????????????????????????).One(&room)

it possible?

Poletaev Roman

unread,
Apr 6, 2016, 5:16:33 PM4/6/16
to mgo-users
for example, i want get room with code "BBB"

четверг, 7 апреля 2016 г., 0:13:30 UTC+3 пользователь Poletaev Roman написал:

Walt Norblad

unread,
Apr 7, 2016, 11:44:28 AM4/7/16
to mgo-users
Hello Roman,

It is possible, but to do so you're going to need to get deeper into Mongo aggregation. 

In Mongo you'll need to stack your aggregation with a pipeline. Mgo has support for pipelines using Pipe(). In Mongo, what you are going to do will look like:

db.users.aggregate(
{$match: {"room.code":ObjectId("56980d05282c61b7d98baa51")}},
{$unwind: "$room"},
{$project: {
"name": "$room.name",
"code": "$room.code"
}}
{$match: {"code":ObjectId("56980d05282c61b7d98baa51")}}
);

What this does is look for all of the users that have a room with the correct code with $match. Then it gets the subdocuments ready for projections with the $unwind. Then it pipes those results into a projection with $project which will allow you to rename the results into a more localized format (it does a little more than that, but Mongo docs will clarify). Finally, from those results it then performs a new selection with another $match. 

This structure is pretty rad and you can do a lot with it. In mgo you'll have it look like:

pipeline :=
[]bson.M{
bson.M{"$match": bson.M{"rooms.code": bson.ObjectIdHex("56980d05282c61b7d98baa51")}},
bson.M{"$unwind": "$rooms"},
bson.M{"$project": bson.M{
"name": "$rooms.name",
"code": "$rooms.code"
}},
bson.M{"$match": bson.M{"code": bson.ObjectIdHex("56980d05282c61b7d98baa51")}},
}

entries := []Rooms
m.collection("users").Pipe(pipeline).All(&entries)

The best news here is that you can just keep on piping more operations together! This is my favorite feature in Mongo.

Finally: I suggest that you open the mongo console and work on getting your Mongo query correct first. It will really help work out all of the tweaks you'll need to make to get it working, especially since Mongo is better at telling you what you did wrong than Go. Go has all sort of other things to worry about (like types, castings, connections, marshaling, etc). And, since there is a strong correlation between the mgo Pipe and Mongo aggregation, you'll be able to suss out what you need to do to make everything work like you want to. 

Best of luck!

Walt Norblad

unread,
Apr 7, 2016, 11:52:27 AM4/7/16
to mgo-users
Oh, and replace the

  "code": bson.ObjectIDHex("56980d05282c61b7d98baa51")

 stuff with 

"code": "BBB"

since you're not working with ObjectId's at that point. But you get the picture! :D

Poletaev Roman

unread,
Apr 7, 2016, 12:26:02 PM4/7/16
to mgo-users

Thank you very much, all clear and understandable :)
Reply all
Reply to author
Forward
0 new messages