通过字段值聚合多个数组

时间:2018-12-27 03:17:35

标签: mongodb mongodb-query

使用如下所示的文档,我试图汇总数据,以便最终输出为每个用户receivedsent值的总和。

文档

{
    "_id" : 1,
    "received" : [
        { "name" : "david", "value" : 15 }, 
        { "name" : "sarah", "value" : 10 }, 
        { "name" : "sarah", "value" : 15 }
    ],
    "sent" : [ 
        { "name" : "david", "value" : 10 }, 
        { "name" : "sarah", "value" : 20 }, 
        { "name" : "david", "value" : 15 }
    ]
}

所需结果(或类似结果)

{
    "name": "david",
    "received": 15,
    "sent": 25
},
{
    "name": "sarah",
    "received": 25,
    "sent": 20
}

我试图平息接收和发送的邮件,但最终会出现很多重复,老实说,我不知道是否可以在不先将数据集带入客户端的情况下创建这种输出。

对StackOverflow的进一步搜索使我进入mongodb aggregate multiple arrays,它提供了合适的答案。我已将其标记为重复。

我根据上述帖子创建的最终解决方案如下;

[
  {
    '$addFields': {
      'received.type': 'received', 
      'sent.type': 'sent'
    }
  }, {
    '$project': {
      'movements': {
        '$concatArrays': [
          '$received', '$sent'
        ]
      }
    }
  }, {
    '$unwind': {
      'path': '$movements'
    }
  }, {
    '$project': {
      'name': '$movements.name', 
      'type': '$movements.type', 
      'value': '$movements.value'
    }
  }, {
    '$group': {
      '_id': '$name', 
      'sent': {
        '$sum': {
          '$cond': {
            'if': {
              '$eq': [
                '$type', 'sent'
              ]
            }, 
            'then': '$value', 
            'else': 0
          }
        }
      }, 
      'received': {
        '$sum': {
          '$cond': {
            'if': {
              '$eq': [
                '$type', 'received'
              ]
            }, 
            'then': '$value', 
            'else': 0
          }
        }
      }
    }
  }
]

1 个答案:

答案 0 :(得分:2)

在顶部添加$match阶段以过滤文档

  • $facet通过在同一文档上发送和接收来计算两个不同的结果
  • $group合并上一阶段的发送者和接收者字段
  • $unwind$unwind展开数组的合并数组
  • $replaceRoot用byBoth替换root
  • $group将结果合并回
  • $project仅用于过滤和投影必填字段

聚合管道

db.ttt.aggregate([
    {$facet : {
        "byReceived" :[
            {$unwind : "$received"},
            {$group: {_id : "$received.name", received : {$sum : "$received.value"}}}
        ],
        "bySent" :[ 
            {$unwind : "$sent"},
            {$group: {_id : "$sent.name", sent : {$sum : "$sent.value"}}}
        ]
    }},
    {$group: {_id:null, byBoth : {$push :{$concatArrays : ["$bySent", "$byReceived"]}}}},
    {$unwind : "$byBoth"},
    {$unwind : "$byBoth"},
    {$replaceRoot: { newRoot: "$byBoth" }},
    {$group : {_id : "$_id", sent : {$sum : "$sent"}, received : {$sum : "$received"}}},
    {$project : {_id:0, name:"$_id", sent:"$sent", received:"$received"}}
])

结果

{ "name" : "david", "sent" : 25, "received" : 15 }
{ "name" : "sarah", "sent" : 20, "received" : 25 }