2016-11-12 41 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

你能告訴我會有多少文件? –

相關問題