Javascript “文件和子文件”分组的$sum$作者;(MongoDB)

Javascript “文件和子文件”分组的$sum$作者;(MongoDB),javascript,node.js,mongodb,mongodb-query,aggregation-framework,Javascript,Node.js,Mongodb,Mongodb Query,Aggregation Framework,这是我的收藏: { "_id" : 10926400, "votes": 131, "author": "Jesse", "comments" : [ { "id" : 1, "votes": 31, "author": "Mirek"

这是我的收藏:

{
        "_id" : 10926400,
        "votes": 131,
        "author": "Jesse",
        "comments" : [
                {
                        "id" : 1,
                        "votes": 31,
                        "author": "Mirek"
                },
                {
                        "id": 2,
                        "votes": 13,
                        "author": "Leszke"
                }
        ]
},
{
        "_id" : 10926401,
        "votes": 75,
        "author": "Mirek",
        "comments" : [
                {
                        "id" : 1,
                        "votes": 17,
                        "author": "Jesse"
                },
                {
                        "id": 2,
                        "votes": 29,
                        "author": "Mirek"
                }
        ]
}
我想要
$sum
每个
作者的
投票和
评论的值

预期输出(
sort$投票:-1
):


不立即可见但可能。这里需要做的是将顶级文档与注释数组相结合,而不复制它。以下是一种方法,首先将内容作为两个数组连接到一个单数数组中,然后将内容分组:

db.collection.aggregate([
    { "$group": {
        "_id": "$_id",
        "author": { 
            "$addToSet": {
                "id": "$_id",
                "author": "$author",
                "votes": "$votes"
            }
        },
        "comments": { "$first": "$comments" }
    }},
    { "$project": {
        "combined": { "$setUnion": [ "$author", "$comments" ] }
    }},
    { "$unwind": "$combined" },
    { "$group": {
        "_id": "$combined.author",
        "votes": { "$sum": "$combined.votes" }
    }},
    { "$sort": { "votes": -1 } }
])
它给出了输出:

{ "_id" : "Jesse", "votes" : 148 }
{ "_id" : "Mirek", "votes" : 135 }
{ "_id" : "Leszke", "votes" : 13 }

即使跳过第一阶段,以不同的方式制作组合阵列:

db.collection.aggregate([
    { "$project": {
        "combined": { 
            "$setUnion": [
                { "$map": {
                    "input": { "$literal": ["A"] },
                    "as": "el",
                    "in": { 
                        "author": "$author",
                        "votes": "$votes"
                    }
                }},
                "$comments"
            ] 
        }
    }},
    { "$unwind": "$combined" },
    { "$group": {
        "_id": "$combined.author",
        "votes": { "$sum": "$combined.votes" }
    }},
    { "$sort": { "votes": -1 } }
])

这些操作使用的是从MongoDB 2.6开始引入的、甚至是这样的操作符。这使得操作更加简单,但在缺少这些操作符的早期版本中,仍然可以按照大致相同的原则进行:

db.collection.aggregate([
    { "$project": {
        "author": 1,
        "votes": 1,
        "comments": 1,
        "type": { "$const": ["A","B"] }
    }},
    { "$unwind": "$type" },
    { "$unwind": "$comments" },
    { "$group": { 
        "_id": {
          "$cond": [
              { "$eq": [ "$type", "A" ] },
              { 
                  "id": "$_id", 
                  "author": "$author",
                  "votes": "$votes"
              },
              "$comments"
          ]
        }
    }},
    { "$group": {
        "_id": "$_id.author",
        "votes": { "$sum": "$_id.votes" }
    }},
    { "$sort": { "votes": -1 } }
])

$const
没有文档记录,但存在于存在聚合框架的所有MongoDB版本中(从2.2开始)。MongoDB 2.6引入了基本上链接到相同底层代码的功能。这里有两种情况使用它,一种是为数组提供模板元素,另一种是引入要展开的数组,以便在两个操作之间提供“二进制选择”。

您可以按如下方式聚合结果:

  • 展开注释数组
  • 将记录分组
    首先计算投票总数 每个作者在其评论中收到的。同时保留原件 贴子要圆滑
  • 按原始post数组展开
  • 现在
    project
    每个作者的总数
  • 按作者姓名和投票进行排序
  • 从每组中选择第一条记录以消除重复项
代码:

订单样本:

{ "_id" : "Leszke", "votes" : 13 }
{ "_id" : "Jesse", "votes" : 148 }
{ "_id" : "Mirek", "votes" : 135 }
db.collection.aggregate([
{$unwind:"$comments"},
{$group:{"_id":null,
         "comments":{$push:"$comments"},
         "post":{$addToSet:{"author":"$author",
                            "votes":"$votes"}}}},
{$unwind:"$comments"},
{$group:{"_id":"$comments.author",
         "votes":{$sum:"$comments.votes"},
         "post":{$first:"$post"}}},
{$unwind:"$post"},
{$project:{"_id":1,
           "votes":{$cond:[{$eq:["$_id","$post.author"]},
                           {$add:["$votes","$post.votes"]},
                           "$votes"]}}},
{$sort:{"_id":-1,"votes":-1}},
{$group:{"_id":"$_id","votes":{$first:"$votes"}}}
])
{ "_id" : "Leszke", "votes" : 13 }
{ "_id" : "Jesse", "votes" : 148 }
{ "_id" : "Mirek", "votes" : 135 }