MongoDB:按属性名称汇总

时间:2018-09-17 18:28:28

标签: mongodb mongodb-query

我有一个集合,其中每个文档看起来都像这样:

{
    "_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 :(得分:0)

这可能是您想要的:

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 ] }
    }
})