根据mongodb中子文档的字段进行分组

时间:2018-07-24 10:30:59

标签: mongodb mongoose aggregation-framework

我在mongodb集合中存储了以下文档:

{
    "_id" : ObjectId("5b56d4072eb1102f495c11ab"),
    "currentStage" : ObjectId("5b06999d889de3bd613ab79d"),
    "stagePermissions" : [
      {
            "_id" : ObjectId("5b55a8cd8bb066994dc21314"),
            "status" : "AWAITING_REVIEW",
            "stage" : ObjectId("5b06999d889de3bd613ab79d"),
      },
      {
            "_id" : ObjectId("5b55a8cd8bb066994dc21354"),
            "status" : "IN_PROGRESS",
            "stage" : ObjectId("5b06999d889de3bd613ac79d"),
      }
    ]

}

我想按stagePermissions.status来获取文档数,其中stagePermissions.stage等于currentStage

Expected OutPut: 
[
  {_id: IN_PROGRESS, count: 1},
  {_id: AWAITING_REVIEW, count: 1}
]

2 个答案:

答案 0 :(得分:1)

您可以在3.6版本中使用以下汇总。

$match$in仅考虑至少一个许可阶段与当前阶段许可匹配的文档。

$unwind来扩展登台权限并过滤与当前登台权限匹配的所有权限。

$group上的阶段权限状态,后跟$sum来计算权限。

db.col.aggregate([
  {"$match":{"$expr":{"$in":["$currentStage","$stagePermissions.stage"]}}},
  {"$unwind":"$stagePermissions"},
  {"$match":{"$expr":{"$eq":["$currentStage","$stagePermissions.stage"]}}},
  {"$group":{"_id":"$stagePermissions.status","count":{"$sum":1}}}
])

3.4更新

$filter以输出阶段许可阶段与当前阶段相同的子文档。

$addFields用过滤器输出覆盖舞台权限数组。

查询将返回所有参与者文档,并将用户子文档的年龄作为参与者年龄。

db.col.aggregate([
  {"$addFields":{"stagePermissions":{"$filter":{"input":"$stagePermissions","cond":{"$eq":["$$this.stage","$currentStage"]}}}}},
  {"$unwind":"$stagePermissions"},
  {"$group":{"_id":"$stagePermissions.status","count":{"$sum":1}}}
])

答案 1 :(得分:1)

更新:

对于Mongo 3.4,您可以利用此聚合查询,因为$expr仅在Mongo 3.6中引入:

db.test.aggregate([
    { $unwind : "$stagePermissions"},
    {$project: {_id : 1, currentStage : 1, stagePermissions : 1, value : {$cmp: ['$currentStage','$stagePermissions.stage']}}},
    {$match: { value : {$eq:0}}},
    { $group :
        {
        _id : "$stagePermissions.status",
        count : {$sum : 1}
        }
    }
])

在这里,我们使用$cmp运算符首先获取比较值,然后使用$match运算符查找性质相同的文档。

================================================ ========================= 输入文件:

{
        "_id" : ObjectId("5b56d4072eb1102f495c11ab"),
        "currentStage" : ObjectId("5b06999d889de3bd613ab79d"),
        "stagePermissions" : [
                {
                        "_id" : ObjectId("5b55a8cd8bb066994dc21314"),
                        "status" : "AWAITING_REVIEW",
                        "stage" : ObjectId("5b06999d889de3bd613ab79d")
                },
                {
                        "_id" : ObjectId("5b55a8cd8bb066994dc21354"),
                        "status" : "IN_PROGRESS",
                        "stage" : ObjectId("5b06999d889de3bd613ab79d")
                }
        ]
}

汇总查询:

db.test.aggregate([
    { $unwind : "$stagePermissions"},
    { $match : {$expr : {$eq : ["$currentStage", "$stagePermissions.stage" ]}}},
    { $group :
        {
        _id : "$stagePermissions.status",
        count : {$sum : 1}
        }
    }
])

输出:

{ "_id" : "IN_PROGRESS", "count" : 1 }
{ "_id" : "AWAITING_REVIEW", "count" : 1 }