简体   繁体   中英

How can I use mongodb projections with Go and mgo?

I am currently trying to extract a single object within a document array inside of mongodb. This is a sample dataset:

"_id" : ObjectId("564aae61e0c4e5dddb07343b"),
"name" : "The Races",
"description" : "Horse races",
"capacity" : 0,
"open" : true,
"type" : 0,
"races" : [
    {
        "_id" : ObjectId("564ab9097628ba2c6ec54423"),
        "race" : {
            "distance" : 3000,
            "user" : {
                "_id" : ObjectId("5648bdbe7628ba189e011b18"),
                "status" : 1,
                "lastName" : "Miranda",
                "firstName" : "Aramys"
            }
        }
    },
    {
        "_id" : ObjectId("564ab9847628ba2c81f2f34a"),
        "bet" : {
            "distance" : 3000,
            "user" : {
                "_id" : ObjectId("5648bdbe7628ba189e011b18"),
                "status" : 1,
                "lastName" : "Miranda",
                "firstName" : "Aramys"
            }
        }
    },{...}
]

I can successfully query using the following in mongo:

db.tracks.find({"_id": ObjectId("564aae61e0c4e5dddb07343b")}, {"races": { $elemMatch: {"_id": ObjectId("564ab9847628ba2c81f2f34a")}}}).pretty()

I am unable to do the same using mgo and have tried the following:

Using nesting (Throws: missing type in composite literal, missing key in map literal)

// Using nesting (Throws: missing type in composite literal, missing key in map literal)
c.Find(bson.M{{"_id": bson.ObjectIdHex(p.ByName("id"))}, bson.M{"races": bson.M{"$elemMatch": bson.M{"_id": bson.ObjectIdHex(p.ByName("raceId"))}}}}).One(&result)

// Using select (Returns empty)
c.Find(bson.M{"_id": bson.ObjectIdHex(p.ByName("id"))}).Select(bson.M{"races._id": bson.ObjectIdHex(p.ByName("raceId"))}).One(&result)

//As an array (Returns empty)
c.Find([]bson.M{{"_id": bson.ObjectIdHex(p.ByName("id"))}, bson.M{"races": bson.M{"$elemMatch": bson.M{"_id": bson.ObjectIdHex(p.ByName("raceId"))}}}}).One(&result)

I am using httprouter and p.ByName("...") invocations are parameters passed to the handler.

Thanks in advance.

Would go with the Select method as the doc states that this enables selecting which fields should be retrieved for the results found, thus the projection using $elemMatch operator can be applied here in conjuction with Select , with your final query looking something like:

c.Find(bson.M{
    "_id": bson.ObjectIdHex(p.ByName("id"))
}).Select(bson.M{
    "races": bson.M{
        "$elemMatch": bson.M{
            "_id": bson.ObjectIdHex(p.ByName("raceId"))
        }
    }
}).One(&result)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM