代码之家  ›  专栏  ›  技术社区  ›  Farhan Tahir

基于mongodb子文档字段分组

  •  1
  • Farhan Tahir  · 技术社区  · 6 年前

    我在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 回复  |  直到 6 年前
        1
  •  1
  •   Subhashree Pradhan    6 年前

    更新:

    对于Mongo3.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 }
    
        2
  •  1
  •   s7vr    6 年前

    您可以在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}}}
    ])