2015-10-31 119 views
1

我有這樣一個集合:如何使用mongodb聚合?

{'speed':45, 'time':1446271000}, 
{'speed':45, 'time':1446271001}, 
{'speed':63, 'time':1446271002},  
{'speed':68, 'time':1446271003}, 
{'speed':70, 'time':1446271004},  
{'speed':59, 'time':1446271005}, 
{'speed':55, 'time':1446271006},  
{'speed':61, 'time':1446271007},  
{'speed':62, 'time':1446271008}, 
{'speed':63, 'time':1446271009},  
{'speed':67, 'time':1446271010} 

我想總結高速(速度> = 60)的記錄,因此結果應該是這樣的:

{'speed':63,'duration':2,'start': 1446271002,'end': 1446271004} 
{'speed':61,'duration':3,'start': 1446271007,'end': 1446271010} 

我應該如何做到這一點?

+1

你想要的結果由起始時間進行排序? – jpaljasma

回答

2

使用下聚合管線,其確實是小於60

下一管道步驟使用$sort操作者通過的時間來重新排列文件的初始$match過濾掉這些文件字段,這對於下一步是必需的,即流水線的$group。在這裏,您可以通過使用$first$last$last從中獲取開始字段和結束字段,這些累加器運算符在您將速度字段作爲關鍵字對文檔進行分組時提取第一個和最後一個時間。

最後管道步驟$project使用$subtract算術運算器,正如其名稱所暗示,減去從endstart創建附加字段,持續時間。最後的管道應該是這樣的:

db.test.aggregate([ 
    { "$match": { "speed": { "$gte": 60 } } }, 
    { "$sort": { "time": 1 } }, 
    { 
     "$group": { 
      "_id": "$speed", 
      "start": { "$first": "$time" }, 
      "end": { "$last": "$time" } 
     } 
    }, 
    { 
     "$project": { 
      "_id": 0, 
      "speed": "$_id", 
      "duration": { "$subtract": [ "$end", "$start" ] }, 
      "start": 1, 
      "end": 1 
     } 
    } 
]) 

樣本輸出:

/* 0 */ 
{ 
    "result" : [ 
     { 
      "start" : 1446271010, 
      "end" : 1446271010, 
      "speed" : 67, 
      "duration" : 0 
     }, 
     { 
      "start" : 1446271007, 
      "end" : 1446271007, 
      "speed" : 61, 
      "duration" : 0 
     }, 
     { 
      "start" : 1446271008, 
      "end" : 1446271008, 
      "speed" : 62, 
      "duration" : 0 
     }, 
     { 
      "start" : 1446271004, 
      "end" : 1446271004, 
      "speed" : 70, 
      "duration" : 0 
     }, 
     { 
      "start" : 1446271003, 
      "end" : 1446271003, 
      "speed" : 68, 
      "duration" : 0 
     }, 
     { 
      "start" : 1446271002, 
      "end" : 1446271009, 
      "speed" : 63, 
      "duration" : 7 
     } 
    ], 
    "ok" : 1 
} 
+1

添加$ sort階段後,它將是完美的。 – jpaljasma

0

我張貼這是因爲現有的答案增加不必要$sort階段的管道,這將導致性能下降。

您需要在您的收藏過濾掉所有的文件,其中speed是​​60使用$match然後操作員$group文檔由「速度」和使用$min$max蓄電池運營商分別返回mimimum和最大價值「的時間「對於不同的羣體。從那裏你需要$project離子階段使用$subtract運營商計算到「持續時間」。當然,.aggregate()方法提供了對aggregation pipeline的訪問。

db.collection.aggregate([ 
    { "$match": { 
     "speed": { "$gte": 60 } 
    }}, 
    { "$group": { 
     "_id": "$speed", 
     "duration": { "$sum": 1 }, 
     "start": { "$min": "$time" }, 
     "end": { "$max": "$time" } 
    }}, 
    { "$project": { 
     "speed": "$_id", 
     "_id": 0, 
     "duration": { "$subtract": [ "$end", "$start" ] }, 
     "start": 1, 
     "end": 1 
    }} 
]) 

其產生:

{ "start" : 1446271010, "end" : 1446271010, "speed" : 67, "duration" : 0 } 
{ "start" : 1446271008, "end" : 1446271008, "speed" : 62, "duration" : 0 } 
{ "start" : 1446271007, "end" : 1446271007, "speed" : 61, "duration" : 0 } 
{ "start" : 1446271004, "end" : 1446271004, "speed" : 70, "duration" : 0 } 
{ "start" : 1446271003, "end" : 1446271003, "speed" : 68, "duration" : 0 } 
{ "start" : 1446271002, "end" : 1446271009, "speed" : 63, "duration" : 7 }