Могу ли я объединить два запроса mongodb в один запрос, используя golang (mgo)?

Я использую golang и mgo, mongodb version is 3.2.9

Например, у меня есть два документа в одной коллекции:

{"groupId" : 4, "name" : "email", "value" : "[email protected]"}

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

Я знаю phoneNumber (value and name) и мне нужно найти адрес электронной почты (значение). Это можно легко сделать двумя запросами: сначала по phoneNumber я нашел groupId, а затем по groupId я нашел электронную почту. Можно ли это сделать одним запросом (используя golang и mgo)?


person I. Len    schedule 28.09.2016    source источник


Ответы (1)


Да, вам нужно будет запустить конвейер агрегации в форме:

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" : "[email protected]" }

из которых следует эквивалентное выражение 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()
person chridam    schedule 28.09.2016