Go中的MongoDB聚合查找(mgo.v2) [英] MongoDB Aggregate lookup in Go (mgo.v2)
问题描述
I'm trying to implement $lookup
functionality in one of my mongoDB queries in go (golang) using the mgo package.
以下是我的收藏集:
文件夹:
"_id" : ObjectId("22222222222222"),
"name" : "Media",
"level" : 1,
"userIDs": [ObjectId("4444444444444")]
文档:
"_id" : ObjectId("11111111111111"),
"title" : "Media Management",
"body" : BinData(0,"PvQ6z2NBm4265duo/e2XsYxA5bXKo="),
"level" : 1,
"folderID" : ObjectId("22222222222222"), // Foreign Key/Field
"userIDs" : [ObjectId("44444444444444")]
下面是我编写的在外壳程序上成功运行的查询:
Below is the query I've written that successfully runs on the shell:
var query = [
{
"$lookup": {
"from": "documents",
"localField": "_id",
"foreignField": "folderID",
"as": "documents",
}
}
,{
"$match": {
"userIDs": ObjectId("userIdHere"), // filder by a userID
"level": {$gte: 0}, // filter by a folder level
},
}
];
db.folders.aggregate(query).pretty().shellPrint();
如果我在shell上运行此脚本,则会得到所需的结果.基本上,folder
集合返回给我,其中包含通过$lookup
链接的完整相关的documents
.我不在这里包括它,因为这个问题似乎已经太久了.
If I run this script on the shell, I get the desired result. Basically, the folder
collection is returned to me containing the full relevant documents
that were linked through the $lookup
. I'm not including it here because this question already seems too long.
我已尝试将此查询转换为 mgo 能够解析和执行的内容.在下面的go代码中:
I've tried to translate this query into something that mgo would be able to parse and execute. Here it is below in go code:
query := bson.M{
"$lookup": bson.M{ // lookup the documents table here
"from": "documents",
"localField": "_id",
"foreignField": "folderID",
"as": "documents",
},
"$match": bson.M{
"level": bson.M{"$gte": user.Level}, // filter by level
"userIDs": user.ID, // filter by user
},
}
pipe := collection.Pipe(query) // querying the "folders" collection
err := pipe.All(&result)
我总是得到相同的错误:字段(管道)的类型错误3 = 4
I always get the same error: wrong type for field (pipeline) 3 != 4
如果我理解正确,那是因为它不能正确地将结果解析回$ result对象.我已尽力确保该结构具有所需的确切结构.我还尝试传递一般的[]interface{}
和空的bson.M{}
对象.仍然会收到相同的错误.
If I understand correctly, it's because it can't properly parse the result back into the $result object. I've done everything I can to ensure the struct has the exact structure that is required. I've also tried to pass in a genereric []interface{}
and an empty bson.M{}
objects. Still receive the same error.
以下是我的文件夹结构:
Below is my Folders struct:
type Folder struct {
ID bson.ObjectId `json:"id" bson:"_id"`
Name string `json:"name"`
Level int `json:"level"`
UserIDs []bson.ObjectId `json:"userIDs" bson:"userIDs"`
Users []User `json:"-" bson:"-"` // doesn't get stored in the database
Documents []Document `json:"-" bson:"-"` // doesn't get stored in the database
}
我还删除了$match
子句,以查看是否可以从该$lookup
查询中完全得到任何东西.但是我仍然遇到相同的错误.
I've also removed the $match
clause to see if I could get anything at all back from that $lookup
query. But I still get the same error.
也许mgo软件包不支持$lookup
?如果是这样,还有其他方法吗? 也许我可以将原始查询文本发送到mongo并接收原始响应并自行解析?
Perhaps the mgo package doesn't support $lookup
? If so, would there be another way? Perhaps I could send the raw query text to mongo and receive the raw response and parse it myself?
推荐答案
找到了解决方案!
技巧是在切片([]bson.M
)中创建查询并稍微更改查询的结构:
The trick was to create the query in a slice ([]bson.M
) and change the structure of the query a bit:
query := []bson.M{{
"$lookup": bson.M{ // lookup the documents table here
"from": "documents",
"localField": "_id",
"foreignField": "folderID",
"as": "documents",
}},
{"$match": bson.M{
"level": bson.M{"$lte": user.Level},
"userIDs": user.ID,
}}}
pipe := collection.Pipe(query)
err := pipe.All(&folders)
我在 mgo的Pipe函数文档中找到了线索.另外,我必须在我的Folders
结构中更改Documents
字段的标签,以便mgo对该字段进行推销:
I found a clue in mgo's Pipe function docs. Also, I had to change the tags for the Documents
field in my Folders
struct for mgo to pupolate that field:
type Folder struct {
ID bson.ObjectId `json:"id" bson:"_id"`
Name string `json:"name"`
Level int `json:"level"`
UserIDs []bson.ObjectId `json:"userIDs" bson:"userIDs"`
Users []User `json:"-" bson:"-"` // doesn't get stored in the database
Documents []Document // `json:"-" bson:"-" Removed this so that mgo can unmarshal
// the documents correctly
}
现在,我只需要找出一种保存Folder
时不将Documents
字段存储在数据库中的方法.
Now I just have to figure out a way to not store the Documents
field in the database when I save a Folder
.
这篇关于Go中的MongoDB聚合查找(mgo.v2)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!