MongoDB: агрегирование по именам свойств - PullRequest
0 голосов
/ 17 сентября 2018

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

{
    "_id" : ObjectId("5b9fe6010c969210d442a377"),
    "statuses" : {
        "SEARCHING" : 3
    },
    "regions" : {
        "eu-central-1" : 1,
"us-west-2": 2
    }
}

Я хочу сгруппировать и преобразовать это в результирующий набор следующим образом:

eu-central-1|us-west-2
1|2

Возможно ли это за один шаг / запрос?

1 Ответ

0 голосов
/ 17 сентября 2018

Это, вероятно, то, что вы хотите:

db.collection.aggregate({
    $project: {
        "regions": { $objectToArray: "$regions" } // convert sub-document into an array of key-value-pairs in order to get hold of the field names
    }
}, {
    $unwind: "$regions" // flatten the "regions" array
}, {
    $group: {
        "_id": "$regions.k",
        "count": { $sum: "$regions.v" } //
    }
})

В качестве альтернативы, если вы действительно хотите получить вывод с разделителями канала, вот что вы должны сделать:

db.collection.aggregate({
    $project: {
        "result": {
            $reduce: {
                "input": { $objectToArray: "$regions" },
                "initialValue": { k: "", v: "" }, // start with empty strings for both key and value
                "in": {
                    k: { $concat: [ "$$value.k", "|", "$$this.k" ] }, // concatenate existing value with "|" followed by currently looked at value for both key and value
                    v: { $concat: [ "$$value.v", "|", { $substr: [ "$$this.v", 0, 1000 ] } ] } // substr is needed to convert an integer field into a string
                    //v: { $concat: [ "$$value.v", "|", { $toString: "$$this.v" } ] } // this works from MongoDB v4.0 onwards and looks a bit cleaner
                }
            }
        }
    }
}, {
    $project: { // remove the leading "|"
        "result.k": { $substr: [ "$result.k", 1, -1 ] },
        "result.v": { $substr: [ "$result.v", 1, -1 ] }
    }
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...