在MongoDB中添加组计数器和项目计数器?

时间:2020-09-01 14:20:37

标签: mongodb

我有这个杰森:

[
  {
    "key": "guitar",
    "name": "john"
  },
  {
    "key": "guitar",
    "name": "paul"
  },
  {
    "key": "guitar",
    "name": "george"
  },
  {
    "key": "drums",
    "name": "ringo"
  }
]

让我们按key分组,然后向每个分组添加项目:

db.collection.aggregate([
  {
    $sort: {
      name: -1
    }
  },
  {
    $group: {
      _id: "$key",
      "projects": {
        "$push": "$$ROOT"
      },
      count: {
        $sum: 1
      }
    }
  },
  {
    $sort: {
      "_id": 1
    }
  }
])

结果:

[
  {
    "_id": "drums",
    "count": 1,
    "projects": [
      {
        "_id": ObjectId("5a934e000102030405000003"),
        "key": "drums",
        "name": "ringo"
      }
    ]
  },
  {
    "_id": "guitar",
    "count": 3,
    "projects": [
      {
        "_id": ObjectId("5a934e000102030405000001"),
        "key": "guitar",
        "name": "paul"
      },
      {
        "_id": ObjectId("5a934e000102030405000000"),
        "key": "guitar",
        "name": "john"
      },
      {
        "_id": ObjectId("5a934e000102030405000002"),
        "key": "guitar",
        "name": "george"
      }
    ]
  }
]

问题:

如何添加这样的计数器:

[
  {
    "_id": "drums",
    "Counter":0,       // <--------------------------------
    "count": 1,
    "projects": [
      {
        "_id": ObjectId("5a934e000102030405000003"),
        "key": "drums",
        "name": "ringo",
        "InnerCounter":0       // <--------------------------------
        
      }
    ]
  },
  {
    "_id": "guitar",
    "Counter":1,       // <--------------------------------
    "count": 3,
    "projects": [
      {
        "_id": ObjectId("5a934e000102030405000001"),
        "key": "guitar",
        "name": "paul",
        "InnerCounter":0       // <--------------------------------
      },
      {
        "_id": ObjectId("5a934e000102030405000000"),
        "key": "guitar",
        "name": "john",
        "InnerCounter":1       // <--------------------------------
      },
      {
        "_id": ObjectId("5a934e000102030405000002"),
        "key": "guitar",
        "name": "george",
        "InnerCounter":2       // <--------------------------------
      }
    ]
  }
]

Live Demo

1 个答案:

答案 0 :(得分:1)

我认为没有其他选择可以执行此操作,您可以尝试使用$unwind通过includeArrayIndex属性在数组中创建索引字段,

db.collection.aggregate([
  { $sort: { name: -1 } },
  {
    $group: {
      _id: "$key",
      projects: { $push: "$$ROOT" }
    }
  },
  // $unwind "projects" array and store index in field "projects.InnerCounter"
  {
    $unwind: {
      path: "$projects",
      includeArrayIndex: "projects.InnerCounter"
    }
  },
  // again group by _id and reconstruct "projects" array
  {
    $group: {
      _id: "$_id",
      projects: { $push: "$projects" },
      count: { $sum: 1 }
    }
  },
  // sort by "_id"
  { $sort: { "_id": 1 } },
  // group by $$ROOT and construct root array 
  {
    $group: {
      _id: null,
      root: { $push: "$$ROOT" }
    }
  },
  // deconstruct root array and add field "Counter" ofr index counter
  {
    $unwind: {
      path: "$root",
      includeArrayIndex: "root.Counter"
    }
  },
  // replace to root
  { $replaceRoot: { newRoot: "$root" } }
])

Playground


projects数组中没有$unwind的另一个选项,

Playground