Go中的MongoDB聚合查找(mgo.v2) [英] MongoDB Aggregate lookup in Go (mgo.v2)

查看:222
本文介绍了Go中的MongoDB聚合查找(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆