我可以使用golang(mgo)在一个查询中聚合两个mongodb查询吗?

时间:2016-09-28 12:09:15

标签: mongodb go aggregation-framework mgo mongodb-aggregation

我使用golangmgomongodb version is 3.2.9

  

例如,我在一个集合中有两个文档:

{"groupId" : 4, "name" : "email", "value" : "11@11.com"}

{"groupId" : 4,"name" : "phoneNumber","value" : "000000000"}

我知道phoneNumber (value and name),我需要找到电子邮件(价值)。 它可以在两个查询中完成:首先通过phoneNumber我找到groupId然后通过groupId我找到了电子邮件。 是否可以在一个查询中执行(使用golang和mgo)?

1 个答案:

答案 0 :(得分:0)

是的,您需要运行以下形式的聚合管道:

var pipeline = [    
    {
        "$group": {
            "_id": "$groupId",
            "entries": {
                "$push": {
                    "name": "$name",
                    "value": "$value"
                }
            }
        }
    },
    {
        "$match": {
            "entries.name" : "phoneNumber", 
            "entries.value" : "000000000"
        }
    },
    {
        "$project": {
            "item": {
                "$arrayElemAt": [
                    {
                        "$filter": {
                            "input": "$entries",
                            "as": "item",
                            "cond": { "$eq": [ "$$item.name", "email" ] }
                        }
                    }, 0
                ]
            }
        }
    },
    {
        "$project": {
            "_id": 0,
            "email": "$item.value"
        }
    }

]);
db.collection.aggregate(pipeline);

示例输出

{ "email" : "11@11.com" }

其中等效的mGo表达式(未经测试):

pipeline := []bson.D{   
    bson.M{
        "$group": bson.M{
            "_id": "$groupId",
            "entries": bson.M{
                "$push": bson.M{
                    "name": "$name",
                    "value": "$value"
                }
            }
        }
    },
    bson.M{
        "$match": bson.M{
            "entries.name" : "phoneNumber", 
            "entries.value" : "000000000"
        }
    },
    bson.M{
        "$project": bson.M{
            "item": bson.M{
                "$arrayElemAt": [
                    bson.M{
                        "$filter": bson.M{
                            "input": "$entries",
                            "as": "item",
                            "cond": bson.M{ "$eq": 
                                []interface{}{  "$$item.name", "email" }    
                            }
                        }
                    }, 0
                ]
            }
        }
    },
    bson.M{
        "$project": bson.M{
            "_id": 0,
            "email": "$item.value"
        }
    }
}

pipe := collection.Pipe(pipeline)
iter := pipe.Iter()