在我的上一篇文章中 ,我演示了使用MongoDB插入5000万个时间事件条目有多快。 这次,我们将利用所有这些数据来推动我们的汇总测试。
这是一个时间事件条目的样子:
{
"_id" : ObjectId("529a2a988cccdb538932d31f"),
"created_on" : ISODate("2012-05-02T06:08:47.835Z"),
"value" : 0.9270193106494844
}
除了默认的主键“ _id”索引,我们还为“ created_on”字段创建了一个,因此这些都是我们的索引:
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "random.randomData",
"name" : "_id_"
},
{
"v" : 1,
"key" : {
"created_on" : 1
},
"ns" : "random.randomData",
"name" : "created_on_1"
}
]
现在,让我们使用所有5000万个条目构建每日报告,计算一天中产生了多少事件,包括该特定日期的最小值,最大值和平均值。
这是我们的脚本的样子:
var start = new Date();
var dataSet = db.randomData.aggregate([
{
$group: {
"_id": {
"year" : {
$year : "$created_on"
},
"dayOfYear" : {
$dayOfYear : "$created_on"
}
},
"count": {
$sum: 1
},
"avg": {
$avg: "$value"
},
"min": {
$min: "$value"
},
"max": {
$max: "$value"
}
}
},
{
$sort: {
"_id.year" : 1,
"_id.dayOfYear" : 1
}
}
]);
if(dataSet.result != null && dataSet.result.length > 0) {
print("Aggregated:" + dataSet.result.length + " days.");
db.dailyReport.insert(dataSet.result);
}
var end = new Date();
print("Aggregation took:" + (end.getTime() - start.getTime())/1000 + "s");
汇总所有数据后,结果将保存到新的DailyReport集合中。 让我们运行脚本,看看我们得到了什么:
D:\wrk\vladmihalcea\mongodb-facts\aggregator\timeseries>mongo random aggregate_daily_report.js
MongoDB shell version: 2.4.6
connecting to: random
Aggregated:367 days.
Aggregation took:129.052s
因此,在129秒内,我们设法为所有这些数据构建了报告。 让我们检查新的收藏并查看我们的每日报告。
{
"_id" : {
"year" : 2012,
"dayOfYear" : 1
},
"count" : 137244,
"avg" : 0.5009360724400802,
"min" : 0.0000013632234185934067,
"max" : 0.9999953350052238
}
{
"_id" : {
"year" : 2012,
"dayOfYear" : 2
},
"count" : 136224,
"avg" : 0.49982110975583033,
"min" : 0.0000023238826543092728,
"max" : 0.9999841095414013
}
由于我们使用Math.random()生成了与时间事件相关的值,因此无论如何我们期望的是平均值,最小值和最大值。 真正有趣的是MongoDB以每秒387440个文档的速度成功处理所有这些数据的速度。
退出此结果后,让我们检查一下随机选择一个小时报告的速度有多快。 我们首先匹配一个小时的条目范围,然后进行分组和排序,最后将结果显示到Mongo Shell中。
var minDate = new Date(2012, 0, 1, 0, 0, 0, 0);
var maxDate = new Date(2013, 0, 1, 0, 0, 0, 0);
var delta = maxDate.getTime() - minDate.getTime();
var fromDate = new Date(minDate.getTime() + Math.random() * delta);
fromDate.setHours(0, 0, 0, 0);
var toDate = new Date(fromDate.getTime() + 60 * 60 * 1000);
print("Aggregating from " + fromDate + " to " + toDate);
var start = new Date();
var dataSet = db.randomData.aggregate([
{
$match: {
"created_on" : {
$gte: fromDate,
$lt : toDate
}
}
},
{
$group: {
"_id": {
"year" : {
$year : "$created_on"
},
"dayOfYear" : {
$dayOfYear : "$created_on"
},
"hour" : {
$hour : "$created_on"
}
},
"count": {
$sum: 1
},
"avg": {
$avg: "$value"
},
"min": {
$min: "$value"
},
"max": {
$max: "$value"
}
}
},
{
$sort: {
"_id.year" : 1,
"_id.dayOfYear" : 1,
"_id.hour" : 1
}
}
]);
if(dataSet.result != null && dataSet.result.length > 0) {
dataSet.result.forEach(function(document) {
printjson(document);
});
}
var end = new Date();
print("Aggregation took:" + (end.getTime() - start.getTime())/1000 + "s");
运行此脚本,我们得到以下结果:
D:\wrk\vladmihalcea\mongodb-facts\aggregator\timeseries>mongo random aggregate_hour_report.js
MongoDB shell version: 2.4.6
connecting to: random
Aggregating from Mon Jul 16 2012 00:00:00 GMT+0300 (GTB Daylight Time) to Mon Jul 16 2012 01:00:00 GMT+0300 (GTB Daylight Time)
{
"_id" : {
"year" : 2012,
"dayOfYear" : 197,
"hour" : 21
},
"count" : 5808,
"avg" : 0.5015344015735451,
"min" : 0.00005716201849281788,
"max" : 0.9998941225931048
}
Aggregation took:0.209s
这是如此之快,以至于我什至不必预先计算基于小时的报告,这意味着我可以在运行时按需轻松生成它。
MongoDB聚合框架非常有用,其性能也不容忽视。 我向您展示的只是简单的示例,不需要任何额外的优化,目的是演示MongoDB的即用型性能。
- 代码可在GitHub上获得 。
翻译自: https://www.javacodegeeks.com/2013/12/mongodb-facts-lightning-speed-aggregation.html