2016-11-12 49 views
0

我对MongoDB很新。考虑下面的集合:是否有可能做出这样的计算并将结果返回给MongoDB?

{ 
"_id" : ObjectId("c0c672fa6db9b3f954732b1a"), 
"date" : ISODate("2016-11-12T00:00:00.000Z"), 
"statistics" : { 
    "members" : { 
     "topPerformers" : { 
      "hours" : [ 
       { 
        "workHour" : 10, 
        "Darth Vader" : 72, 
        "Walrus Man" : 80, 
        "Imperial Stromtrooper" : 60 
       }, 
       { 
        "workHour" : 11, 
        "Darth Vader" : 142, 
        "Walrus Man" : 115, 
        "Imperial Stromtrooper" : 100 
       }, 
       { 
        "workHour" : 12, 
        "Darth Vader" : 116, 
        "Walrus Man" : 81, 
        "Imperial Stromtrooper" : 113 
       }, 
       { 
        "workHour" : 13, 
        "Darth Vader" : 128, 
        "Walrus Man" : 90, 
        "Imperial Stromtrooper" : 141 
       }, 
       { 
        "workHour" : 14, 
        "Darth Vader" : 95, 
        "Walrus Man" : 118, 
        "Imperial Stromtrooper" : 116 
       }, 
       { 
        "workHour" : 15, 
        "Darth Vader" : 91, 
        "Walrus Man" : 93, 
        "Imperial Stromtrooper" : 124 
       }, 
       { 
        "workHour" : 16, 
        "Darth Vader" : 144, 
        "Walrus Man" : 95, 
        "Imperial Stromtrooper" : 111 
       }, 
       { 
        "workHour" : 17, 
        "Darth Vader" : 143, 
        "Walrus Man" : 72, 
        "Imperial Stromtrooper" : 136 
       }, 
       { 
        "workHour" : 18, 
        "Darth Vader" : 54, 
        "Walrus Man" : 88, 
        "Imperial Stromtrooper" : 87 
       }, 
       { 
        "workHour" : 19, 
        "Darth Vader" : 82, 
        "Walrus Man" : 146, 
        "Imperial Stromtrooper" : 67 
       }, 
       { 
        "workHour" : 20, 
        "Darth Vader" : 88, 
        "Walrus Man" : 136, 
        "Imperial Stromtrooper" : 52 
       }, 
       { 
        "workHour" : 21, 
        "Darth Vader" : 92, 
        "Walrus Man" : 113, 
        "Imperial Stromtrooper" : 124 
       }, 
       { 
        "workHour" : 22, 
        "Darth Vader" : 91, 
        "Walrus Man" : 68, 
        "Imperial Stromtrooper" : 128 
       }, 
       { 
        "workHour" : 23, 
        "Darth Vader" : 125, 
        "Walrus Man" : 64, 
        "Imperial Stromtrooper" : 84 
       }, 
       { 
        "workHour" : 0, 
        "Darth Vader" : 97, 
        "Walrus Man" : 108, 
        "Imperial Stromtrooper" : 75 
       } 
      ] 
     } 
    } 
} 
} 

1天每一个记录是这样的,比如我有收集每天在30份文件。我可以用我想要的日期范围做db.getCollection('name').find({ date: { $gte: new ISODate(), $lt: new ISODate() } }),然后如果我选择了整个月的记录,我可以循环使用statistics.members.topPerformers.hours并计算当天每个成员在客户端的总数,如下所示:

statistics.members.topPerformers.hours.forEach((hour) => { 
      Object 
      .keys(hour) 
      .filter(key => key !== 'workHour') 
      .forEach((key) => { 
       result[key] = (result[key] || 0) + hour[key]; 
      }); 
     }); 

我能做到这一点的服务器端与蒙戈并返回修改后的结果是这样一个例子:

{ 
"_id" : ObjectId("c0c672fa6db9b3f954732b1a"), 
"date" : ISODate("2016-11-12T00:00:00.000Z"), 
"statistics" : { 
    "members" : { 
     "topPerformers" : { 
      "hours" : [ 
       { 
        "workHour" : 10, 
        "Darth Vader" : 2512, 
        "Walrus Man" : 1423, 
        "Imperial Stromtrooper" : 1487 
       }, 
      ] 
      } 
     } 
    } 
+0

您应该能够使用聚合与类似流水线的比赛,团体,放松,组]得到你正在寻找的结果。 稍后会检查是否有人扩展了此评论,但如果不是,我可以尝试举个例子,当我有一点时间时。 匹配你想要的任何东西,按日期分组,解开statistics.members.topPerformers.hours,如何获得输出格式组 –

回答

0

你可以运行聚合管道,它利用了$match操作流水线阶段来过滤col中的文档以前的$unwind运算符可以将嵌入的小时数组展平,然后您可以使用管道对非规格化文档进行分组并计算总和。

以下蒙戈外壳操作演示上面:

var start = new Date(); 
start.setHours(0,0,0,0); 

var end = new Date(); 
end.setHours(23,59,59,999); 

db.collection.aggregate([ 
    { "$match": { "date": { "$gte": start, "$lte": end } } }, 
    { "$unwind": "$statistics.members.topPerformers.hours" }, 
    { 
     "$group": { 
      "_id": "$_id", 
      "date": { "$first": "$date" }, 
      "workHour" : { 
       "$sum": "$statistics.members.topPerformers.hours.workHour" 
      }, 
      "Darth Vader" : { 
       "$sum": "$statistics.members.topPerformers.hours.Darth Vader" 
      }, 
      "Walrus Man" : { 
       "$sum": "$statistics.members.topPerformers.hours.Walrus Man" 
      }, 
      "Imperial Stromtrooper" : { 
       "$sum": "$statistics.members.topPerformers.hours.Imperial Stromtrooper" 
      } 
     } 
    } 
]); 

样本输出

{ 
    "_id" : ObjectId("c0c672fa6db9b3f954732b1a"), 
    "date" : ISODate("2016-11-12T00:00:00.000Z"), 
    "workHour" : 231.0, 
    "Darth Vader" : 1560.0, 
    "Walrus Man" : 1467.0, 
    "Imperial Stromtrooper" : 1518.0 
} 

虽然不是必需的,你可以重塑通过附加一个$project最后文件领域管道如下

db.collection.aggregate([ 
    { "$match": { "date": { "$gte": start, "$lte": end } } }, 
    { "$unwind": "$statistics.members.topPerformers.hours" }, 
    { 
     "$group": { 
      "_id": "$_id", 
      "date": { "$first": "$date" }, 
      "workHour" : { 
       "$sum": "$statistics.members.topPerformers.hours.workHour" 
      }, 
      "Darth Vader" : { 
       "$sum": "$statistics.members.topPerformers.hours.Darth Vader" 
      }, 
      "Walrus Man" : { 
       "$sum": "$statistics.members.topPerformers.hours.Walrus Man" 
      }, 
      "Imperial Stromtrooper" : { 
       "$sum": "$statistics.members.topPerformers.hours.Imperial Stromtrooper" 
      } 
     } 
    }, 
    { 
     "$project": { 
      "date": 1, 
      "statistics.members.topPerformers.hours.workHour": "$workHour",, 
      "statistics.members.topPerformers.hours.Darth Vader": "$Darth Vader", 
      "statistics.members.topPerformers.hours.Walrus Man": "$Walrus Man", 
      "statistics.members.topPerformers.hours.Imperial Stromtrooper": "$Imperial Stromtrooper" 
     } 
    } 
]) 

输出

{ 
    "_id" : ObjectId("c0c672fa6db9b3f954732b1a"), 
    "date" : ISODate("2016-11-12T00:00:00.000Z"), 
    "statistics" : { 
     "members" : { 
      "topPerformers" : { 
       "hours" : { 
        "workHour" : 231.0, 
        "Darth Vader" : 1560.0, 
        "Walrus Man" : 1467.0, 
        "Imperial Stromtrooper" : 1518.0 
       } 
      } 
     } 
    } 
} 
+0

感谢您的帮助!值内的键是未知的。所以我不能“达斯维达”:{ “$ sum”:“$ statistics.members.topPerformers.hours.Darth Vader” },例如,我应该像现在一样坚持客户端解决方案吗?生成我需要的结果需要大约1秒的时间,Mongo会更快地生成结果吗? –

+0

如果密钥未知,那么除非您更改模式,否则上述解决方案将不会有帮助。否则,您的客户端解决方法应该适用于小数据集,但是当您遇到大量文档或子文档时,可能会遭受性能处罚。 – chridam

+0

你能告诉我会有多少文件? –

相关问题