你可以使用Go和mgo来使用MongoDB的投影功能。

huangapple go评论82阅读模式
英文:

How can I use mongodb projections with Go and mgo?

问题

我目前正在尝试从MongoDB中的文档数组中提取单个对象。这是一个示例数据集:

"_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"
            }
        }
    },
    {...}
]

你可以使用以下Mongo查询成功地提取数据:

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

但是,使用mgo库时,你尝试了以下方法却无法实现相同的功能:

使用嵌套(抛出错误:missing type in composite literal, missing key in map literal):

// 使用嵌套(抛出错误: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)

使用select(返回空):

// 使用select(返回空)
c.Find(bson.M{"_id": bson.ObjectIdHex(p.ByName("id"))}).Select(bson.M{"races._id": bson.ObjectIdHex(p.ByName("raceId"))}).One(&result)

作为数组(返回空):

// 作为数组(返回空)
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)

你正在使用httprouter,并且p.ByName("...")是传递给处理程序的参数。

提前感谢你的帮助。

英文:

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.

答案1

得分: 9

会使用**Select方法,因为文档中指出它可以选择要检索的结果中的字段,因此可以将使用$elemMatch运算符的投影与Select**结合使用,在最终的查询中,代码可能如下所示:

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)
英文:

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)

huangapple
  • 本文由 发表于 2015年11月17日 15:36:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/33751451.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定