我现在坚持这个。 我的收藏品如下:
{
"_id": ObjectId("55820292e3dc84aa0c9c63bc"),
"creation_at": ISODate("2015-06-17T23:28:18.896Z"),
"cpu": 36,
"mem": "1.08"
}
每隔30秒将一些日志放入其中。 我希望按时间段获取摘要信息,例如:
[
{
'interval': ['2015-06-07 13:00:00', '2015-06-07 13:59:59'],
'cpu': {
'max': 20,
'min': 1,
'avg': 3
},
'memory': {
'max': 40,
'min': 35,
'avg': 38
}
},
{
'interval': ['2015-06-07 14:00:00', '2015-06-07 14:59:59'],
'cpu': { ... },
'memory': { ... }
},
...
...
...
]
从mongo docs中我发现这可以通过聚合框架实现,但我仍然坚持生成时间间隔。 你能建议我吗?
答案 0 :(得分:1)
好的内存在您的数据中显示为“字符串”,因此除非您转换它,否则将会出现问题。对于数值,对于Date Aggregation Operators:
的聚合框架来说这很容易db.collection.aggregate([
{ "$group": {
"_id": {
"year": { "$year": "$creation_at" },
"month": { "$month": "$creation_at" },
"day": { "$day": "$creation_at" },
"hour": { "$hour": "$creation_at" }
},
"minCpu": { "$min": "$cpu" },
"maxCpu": { "$max": "$cpu" },
"avgCpu": { "$avg": "$cpu" },
"minMem": { "$min": "$mem" },
"maxMem": { "$max": "$mem" },
"avgMem": { "$avg": "$mem" }
}}
])
这是间隔一小时,但当然有更精细的操作员。当然,聚合字段不能像没有进一步投影那样“嵌套”出来。但如果你愿意,你也可以这样做。
如果日期聚合运算符看起来太简洁或“时间戳”值更多你的东西那么你可以使用日期数学:
db.collection.aggregate([
{ "$group": {
"_id": {
"$subtract": [
{ "$subtract": [ "$creation_at", new Date("1970-01-01") ] },
{ "$mod": [
{ "$subtract": [ "$creation_at", new Date("1970-01-01") ] },
1000 * 60 * 60
]}
]
},
"minCpu": { "$min": "$cpu" },
"maxCpu": { "$max": "$cpu" },
"avgCpu": { "$avg": "$cpu" },
"minMem": { "$min": "$mem" },
"maxMem": { "$max": "$mem" },
"avgMem": { "$avg": "$mem" }
}}
])
由于从日期“减去”“纪元日期”值会以毫秒为单位返回当前时间作为数字。
你的“字符串”在这里是一个问题,你总是可以回到mapReduce:
db.collection.mapReduce(
function() {
var date = this.creation_at.valueOf()
- ( this.creation_at.valueOf % ( 1000 * 60 * 60 ) );
emit( new Date(date), {
cpu: {
min: parseInt(this.cpu),
max: parseInt(this.cpu),
avg: parseInt(this.cpu)
},
mem: {
min: parseFloat(this.mem),
max: parseFloat(this.mem),
avg: parseFloat(this.mem)
}
})
},
function(key,values) {
var result = {
cpu: { min: 0, max: 0, avg: 0 },
mem: { min: 0, max: 0, avg: 0 }
};
result.cpu.min = Math.min.apply( null, values.map(function(el) {
return el.cpu.min;
}));
result.cpu.max = Math.max.apply( null, values.map(function(el) {
return el.cpu.max;
}));
result.cpu.avg = Array.sum(values.map(function(el) {
return el.cpu.avg
})) / values.length;
result.mem.min = Math.min.apply( null, values.map(function(el) {
return el.mem.min;
}));
result.mem.max = Math.max.apply( null, values.map(function(el) {
return el.mem.max;
}));
result.mem.avg = Array.sum(values.map(function(el) {
return el.mem.avg
})) / values.length;
return result;
},
{ "out": { "inline": 1 } }
)
并且可能比快速的hacky方法更好地清理减速器逻辑。
但基本原则是从日期到分组提取间隔,然后对结果字段进行数学运算。