嵌套字段上的MongoDB聚合$ size

时间:2018-09-21 01:15:53

标签: javascript node.js mongodb aggregation-framework

我正在尝试进行棘手的聚合,以返回集合中文档中嵌套数组的大小。

以下是重新创建示例数据的方法:

db.test.insert({
    projects: [
        {
            _id: 1,
            comments: [
                'a',
                'b',
                'c'
            ]
        },
        {
            _id: 2,
            comments: [
                'a',
                'b'
            ]
        },
        {
            _id: 3,
            comments: []
        }
    ]
})

我要执行的聚合在这里:

db.test.aggregate([
    // enter aggregation here
])

这是所需的输出:

[{
    projects: [
        {
            _id: 1,
            comment_count: 3
        },
        {
            _id: 2,
            comment_count: 2
        },
        {
            _id: 3,
            comment_count: 0
        }
    ]
}]

我正在努力写这篇文章。如果我尝试以下操作:

"projects.comment_count": {"$size": }

结果返回结果数组的大小:

[{
    projects: [
        {
            _id: 1,
            comment_count: 3
        },
        {
            _id: 2,
            comment_count: 3
        },
        {
            _id: 3,
            comment_count: 3
        }
    ]
}]

如果我尝试使用$ map方法,如下所示:

"projects.comment_count": { 
    "$map": { 
        "input": "$projects", 
        "as": "project", 
        "in": {
            "$size": "$$project.comments"
        } 
    } 
}

它将为该数组中的每个对象返回一个看起来像这样的数组:

[{
    projects: [
        {
            _id: 1,
            comment_count: [3, 2, 0]
        },
        {
            _id: 2,
            comment_count: [3, 2, 0]
        },
        {
            _id: 3,
            comment_count: [3, 2, 0]
        }
    ]
}]

谢谢!

2 个答案:

答案 0 :(得分:2)

这是使用$unwind$group,然后使用$push$size的想法。最后$project摆脱了_id

db.collection.aggregate([
  {
    "$unwind": "$projects"
  },
  {
    $group: {
      _id: null,
      "projects": {
        $push: {
          _id: "$projects._id",
          comment_count: {
            $size: "$projects.comments"
          }
        }
      }
    }
  },
  {
    "$project": {
      "_id": 0
    }
  }
])

您可以see the result here

答案 1 :(得分:1)

您需要指定 $map聚合的in参数内的每个字段,最后将$sizecomments数组一起使用。

类似这样的东西

db.collection.aggregate([
  { "$project": {
    "projects": {
      "$map": {
        "input": "$projects",
        "in": {
          "_id": "$$this._id",
          "comment_count": {
            "$size": "$$this.comments"
          }
        }
      }
    }
  }}
])

输出

[
  {
    "projects": [
      {
        "_id": 1,
        "comment_count": 3
      },
      {
        "_id": 2,
        "comment_count": 2
      },
      {
        "_id": 3,
        "comment_count": 0
      }
    ]
  }
]