17x*_*nde 4 go mongodb mongodb-query mgo aggregation-framework
我试图实现$lookup使用中去(golang)在我的MongoDB查询的一个功能氧化镁包.
以下是我的收藏:
文件夹:
"_id" : ObjectId("22222222222222"),
"name" : "Media",
"level" : 1,
"userIDs": [ObjectId("4444444444444")]
Run Code Online (Sandbox Code Playgroud)
文件:
"_id" : ObjectId("11111111111111"),
"title" : "Media Management",
"body" : BinData(0,"PvQ6z2NBm4265duo/e2XsYxA5bXKo="),
"level" : 1,
"folderID" : ObjectId("22222222222222"), // Foreign Key/Field
"userIDs" : [ObjectId("44444444444444")]
Run Code Online (Sandbox Code Playgroud)
下面是我写的在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();
Run Code Online (Sandbox Code Playgroud)
如果我在shell上运行此脚本,我会得到所需的结果.基本上,该folder集合将返回给我,其中包含documents通过该链接链接的完整相关内容$lookup.我不在这里,因为这个问题似乎已经太久了.
我试图将此查询转换为mgo能够解析和执行的内容.这里是下面的代码:
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)
Run Code Online (Sandbox Code Playgroud)
我总是得到同样的错误:字段(管道)3的错误类型!= 4
如果我理解正确,那是因为它无法正确地将结果解析回$ result对象.我已尽我所能确保结构具有所需的确切结构.我也尝试传递一个genereric []interface{}和一个空bson.M{}对象.仍然收到相同的错误.
下面是我的文件夹结构:
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
}
Run Code Online (Sandbox Code Playgroud)
我还删除了该$match条款,看看我是否可以从该$lookup查询得到任何结果.但我仍然得到同样的错误.
也许mgo包不支持$lookup?如果是这样,会有另一种方式吗?也许我可以将原始查询文本发送到mongo并接收原始响应并自己解析它?
找到了解决方案!
诀窍是在slice([]bson.M)中创建查询并稍微更改查询的结构:
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)
Run Code Online (Sandbox Code Playgroud)
我在mgo的Pipe函数文档中找到了一个线索.另外,我必须更改Documents我的Foldersstruct for mgo中字段的标记,以便对该字段进行pupolate:
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
}
Run Code Online (Sandbox Code Playgroud)
现在我只需要找出一种方法,Documents在我保存时不将字段存储在数据库中Folder.
| 归档时间: |
|
| 查看次数: |
3035 次 |
| 最近记录: |