2

我有一個蒙戈分片羣集,其中我從一個虛擬機監控系統(ZABBIX ECC)保存數據。現在我想從數據庫中獲取一些信息,例如在一個虛擬機的最後2天內使用avg memfree。 我讀了關於聚合的教程和與sql的比較,但我不明白如何查詢時間系列文檔(如mongo在網絡研討會上所寫的建議)。如何聚合時間序列文件MongoDB中

例子:我有一個集合與許多這些文檔的(一個DOC表示1小時):

"_id" : ObjectId("5558ab960e8956234285de14"), 
    "timestamp_hour" : ISODate("2014-10-13T23:00:00.000+02:00"), 
    "name" : "memfree", 
    "unity" : "B", 
    "values" : { 
     "0" : { 
      "0" : 2041004032.0000000000000000, 
      "1" : 2041004032.0000000000000000, 
      "2" : 2041004032.0000000000000000, 
      "3" : 2041004032.0000000000000000, 
      "4" : 2041004032.0000000000000000, 
      "5" : 2041004032.0000000000000000, 
      "6" : 2041004032.0000000000000000, 
      "7" : 2041004032.0000000000000000, 
      "8" : 2041004032.0000000000000000, 
      "9" : 2041004032.0000000000000000, 
      "10" : 2041004032.0000000000000000, 
      "11" : 2041004032.0000000000000000, 
      "12" : 2041004032.0000000000000000, 
      "13" : 2041004032.0000000000000000, 
      "14" : 2041004032.0000000000000000, 
      "15" : 2041004032.0000000000000000, 
      "16" : 2041004032.0000000000000000, 
      "17" : 2041004032.0000000000000000, 
      "18" : 2041004032.0000000000000000, 
      "19" : 2041004032.0000000000000000, 
      "20" : 2041004032.0000000000000000, 
      "21" : 2041004032.0000000000000000, 
      "22" : 2041004032.0000000000000000, 
      "23" : 2041004032.0000000000000000, 
      "24" : 2041004032.0000000000000000, 
      "25" : 2041004032.0000000000000000, 
      "26" : 2041004032.0000000000000000, 
      "27" : 2041004032.0000000000000000, 
      "28" : 2041004032.0000000000000000, 
      "29" : 2041004032.0000000000000000, 
      "30" : 2041004032.0000000000000000, 
      "31" : 2041004032.0000000000000000, 
      "32" : 2041004032.0000000000000000, 
      "33" : 2041004032.0000000000000000, 
      "34" : 2041004032.0000000000000000, 
      "35" : 2041004032.0000000000000000, 
      "36" : 2041004032.0000000000000000, 
      "37" : 2041004032.0000000000000000, 
      "38" : 2041004032.0000000000000000, 
      "39" : 2041004032.0000000000000000, 
      "40" : 2041004032.0000000000000000, 
      "41" : 2041004032.0000000000000000, 
      "42" : 2041004032.0000000000000000, 
      "43" : 2041004032.0000000000000000, 
      "44" : 2041004032.0000000000000000, 
      "45" : 2041004032.0000000000000000, 
      "46" : 2041004032.0000000000000000, 
      "47" : 2041004032.0000000000000000, 
      "48" : 2041004032.0000000000000000, 
      "49" : 2041004032.0000000000000000, 
      "50" : 2041004032.0000000000000000, 
      "51" : 2041004032.0000000000000000, 
      "52" : 2041004032.0000000000000000, 
      "53" : 2041004032.0000000000000000, 
      "54" : 2041004032.0000000000000000, 
      "55" : 2041004032.0000000000000000, 
      "56" : 2041004032.0000000000000000, 
      "57" : 2041004032.0000000000000000, 
      "58" : 2041004032.0000000000000000, 
      "59" : 2041004032.0000000000000000 
     }, 
     "1" : { 
      "0" : 2041004032.0000000000000000, 
      "1" : 2041004032.0000000000000000, 
      "2" : 2041004032.0000000000000000, 
      "3" : 2041004032.0000000000000000, 
      "4" : 2041004032.0000000000000000, 
      "5" : 2041004032.0000000000000000, 
      "6" : 2041004032.0000000000000000, 
      "7" : 2041004032.0000000000000000, 
      "8" : 2041004032.0000000000000000, 
      "9" : 2041004032.0000000000000000, 
      "10" : 2041004032.0000000000000000, 
      "11" : 2041004032.0000000000000000, 
      "12" : 2041004032.0000000000000000, 
      "13" : 2041004032.0000000000000000, 
      "14" : 2041004032.0000000000000000, 
      "15" : 2041004032.0000000000000000, 
      "16" : 2041004032.0000000000000000, 
      "17" : 2041004032.0000000000000000, 
      "18" : 2041004032.0000000000000000, 
      "19" : 2041004032.0000000000000000, 
      "20" : 2041004032.0000000000000000, 
      "21" : 2041004032.0000000000000000, 
      "22" : 2041004032.0000000000000000, 
      "23" : 2041004032.0000000000000000, 
      "24" : 2041004032.0000000000000000, 
      "25" : 2041004032.0000000000000000, 
      "26" : 2041004032.0000000000000000, 
      "27" : 2041004032.0000000000000000, 
      "28" : 2041004032.0000000000000000, 
      "29" : 2041004032.0000000000000000, 
      "30" : 2041004032.0000000000000000, 
      "31" : 2041004032.0000000000000000, 
      "32" : 2041004032.0000000000000000, 
      "33" : 2041004032.0000000000000000, 
      "34" : 2041004032.0000000000000000, 
      "35" : 2041004032.0000000000000000, 
      "36" : 2041004032.0000000000000000, 
      "37" : 2041004032.0000000000000000, 
      "38" : 2041004032.0000000000000000, 
      "39" : 2041004032.0000000000000000, 
      "40" : 2041004032.0000000000000000, 
      "41" : 2041004032.0000000000000000, 
      "42" : 2041004032.0000000000000000, 
      "43" : 2041004032.0000000000000000, 
      "44" : 2041004032.0000000000000000, 
      "45" : 2041004032.0000000000000000, 
      "46" : 2041004032.0000000000000000, 
      "47" : 2041004032.0000000000000000, 
      "48" : 2041004032.0000000000000000, 
      "49" : 2041004032.0000000000000000, 
      "50" : 2041004032.0000000000000000, 
      "51" : 2041004032.0000000000000000, 
      "52" : 2041004032.0000000000000000, 
      "53" : 2041004032.0000000000000000, 
      "54" : 2041004032.0000000000000000, 
      "55" : 2041004032.0000000000000000, 
      "56" : 2041004032.0000000000000000, 
      "57" : 2041004032.0000000000000000, 
      "58" : 2041004032.0000000000000000, 
      "59" : 2041004032.0000000000000000 
.... 

我想知道從平均memfree '2014-10-13T23:00:00.000' 以'2014-10-15T23:00:00.000'。所以我需要總結從13到15(3600 * 24 * 2值)的所有值。 我想查詢將是這樣的,但我不知道怎麼解釋的平均命令.....

db.metrics.aggregate([ 
    { $match: { name: 'memfree' ,timestamp_hour:{$gte: ISODate("2014-10-13T23:00:00.000+02:00")},timestamp_hour:{$lte: ISODate("2014-10-15T23:00:00.000+02:00")} } }, 
    { 
    $group: { 
     _id: "$name", 
     avg: { $avg: "how can get all the values??" } 
    } 
    } 
]) 

什麼建議嗎?

感謝

編輯: 正確答案(適用於一對多指標)是:

map = function() { 
    for (var min in this.values) 
    for (sec in this.values[min]){ 
     data = {value: {}, count: {}} 
     data.value[this.name] = this.values[min][sec] 
     data.count[this.name] = 1 
     emit(this.name, data); 
    } 
} 

reduce = function(key, values) { 
    var sum = values.reduce(function(a, b) { 
    out = {value: {}, count: {},avg:0} 
    for (k in b.value){ 
     incount = a.count[k] || 0 
     invalue = a.value[k] || 0 
     out.value[k] = b.value[k]+invalue 
     out.count[k] = b.count[k]+incount 
    } 
    out.avg = out.value[k]/out.count[k] 
    return out 
    }); 
    return sum; 
} 


printjson(db.node0208_26608.mapReduce(map, reduce, 
       { 
       query: { name: {$in:['ioutil','memtotal','memfree']} , 
          timestamp_hour:{$gte: ISODate("2014-09-22T00:00:00.000+02:00")}, 
          timestamp_hour:{$lte: ISODate("2014-09-28T23:00:00.000+02:00")} 
         }, 
       //to write directly on a collection 
       //out:{merge: "map_reduce_out"}, 
      out: {inline:1}, 
      verbose:true 
       }) 
) 

會產生這樣的結果:

{ 
     "results" : [ 
       { 
         "_id" : "ioutil", 
         "value" : { 
           "value" : { 
             "ioutil" : 2495762.106280909 
           }, 
           "count" : { 
             "ioutil" : 601200 
           }, 
           "avg" : 4.15130090865088 
         } 
       }, 
       { 
         "_id" : "memfree", 
         "value" : { 
           "value" : { 
             "memfree" : 28500447903744 
           }, 
           "count" : { 
             "memfree" : 601200 
           }, 
           "avg" : 47405934.636966065 
         } 
       }, 
       { 
         "_id" : "memtotal", 
         "value" : { 
           "value" : { 
             "memtotal" : 635834327040000 
           }, 
           "count" : { 
             "memtotal" : 594000 
           }, 
           "avg" : 1070428160 
         } 
       } 
     ], 
     "counts" : { 
       "input" : NumberLong(499), 
       "emit" : NumberLong(1796400), 
       "reduce" : NumberLong(11), 
       "output" : NumberLong(3) 
     }, 
     "timeMillis" : 37956, 
     "timing" : { 
       "shardProcessing" : 37948, 
       "postProcessing" : 8 
     }, 
     "shardCounts" : { 
       "192.168.0.19:27017" : { 
         "input" : 165, 
         "emit" : 594000, 
         "reduce" : 4, 
         "output" : 1 
       }, 
       "192.168.0.20:27017" : { 
         "input" : 334, 
         "emit" : 1202400, 
         "reduce" : 7, 
         "output" : 2 
       } 
     }, 
     "postProcessCounts" : { 
       "192.168.0.21:27017" : { 
         "input" : NumberLong(3), 
         "reduce" : NumberLong(0), 
         "output" : NumberLong(3) 
       } 
     }, 
     "ok" : 1 
} 
+0

你可能想要考慮這個[**答案**](http://stackoverflow.com/a/30304776/)。 – chridam

回答

1

這將是很難使用,以實現聚合框架。但它與MapReduce很好地協作。東西沿線(未經測試):

// collect *individual* values 
map = function() { 
    for (var min in this.values) 
    for (sec in this.values[min]) 
     data = {value: {}, count: {}} 
     data.value[this.name] = this.values[min][sec] 
     data.count[this.name] = 1 
     emit(null, data); 
} 

// sum values and count 
reduce = function(key, values) { 
    var sum = values.reduce(function(a, b) { 
    out = {value: {}, count: {}} 
    for (k in b.value) 
     incount = a.count[k] || 0 
     invalue = a.value[k] || 0 
     out.value[k] = b.value[k]+invalue 
     out.count[k] = b.count[k]+incount 

    return out 
    }); 
    return sum; 
} 
+0

好的......如果我想爲3個度量AVG(memfree,cputil,diskfree)我有不同的查詢重複相同的常規3倍或有可能把或查詢組的結果在最後陳述?也許用emit(this.name,this.values [min] [sec]); ? – SUPERALEX

+0

@SUPERALEX我沒有時間寫詳細信息,但我已經編輯了我的答案 –

+0

謝謝第一個解決方案的作品;我稍微改正了第二個。只有我不明白的是,如果我使用相同的度量標準運行這兩個解決方案,它會給略微不同的平均值,但只有當度量標準不具有整數值時...我認爲存在一些舍入問題,但我不在乎很多 – SUPERALEX