Search code examples
mongodbgomgo

How to retrieve a mongo document with an array of objects that have matching attribute


I have a collection of user documents, each with an embedded array of clients. Each object in the array has a clientID.

I wanted to retrieve the user document with a client, in the clients array, that has a clientID matching a passed clientID.

But all the examples I have come across just retrieve the object instead of returning the document. I wanted to do this using the mgo library

var results []model.Clients   
err := db.C("users").Find(nil).Select(bson.M{"clients": bson.M{"$elemMatch":q }}).All(&results)

The above returns just a clients array. But I wanted a users array.

[
    {
        "userID": "1",
        clients: [
            {
                "clientID": "12",
                "data": {},
                "customers": [
                    "customerID": "0123",
                    "data": {

                    }
                ]
            },
            {
                "clientID": "123",
                "data": {},
                "customers": [
                    "customerID": "0123",
                    "data": {

                    }
                ]
            }
        ]
    },
    {
        "userID": "2",
        clients: [
            {
                "clientID": "12",
                "data": {},
                "customers": [
                    "customerID": "0123",
                    "data": {

                    }
                ]
            },
            {
                "clientID": "13",
                "data": {},
                "customers": [
                    "customerID": "0123",
                    "data": {

                    }
                ]
            }
        ]
    }
]

Solution

  • Query.Select() enables selecting which fields should be retrieved for the results, not for specifying filter criteria. Filter criterial should be passed to Collection.Find().

    var results []model.User   
    err := db.C("users").Find(bson.M{"clients": bson.M{"$elemMatch":q}}).All(&results)
    

    You may also use "clients.clientID" to designate the clientID in the clients array:

    var results []model.User   
    err := db.C("users").Find(bson.M{"clients.clientID": "12"}).All(&results)