Автор оригинала: Vlad Mihalcea.
В моем предыдущем посте я продемонстрировал , как быстро вы можете вставить 50 миллионов записей о событиях времени с помощью MongoDB. На этот раз мы будем использовать все эти данные для проведения наших агрегационных тестов.
Вот как выглядит запись о событии времени:
{
"_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"
}
]
Теперь давайте используем все 50 миллионов записей для построения ежедневного отчета, подсчитывая, сколько событий было сгенерировано за день, включая минимальное, максимальное и среднее значение за этот конкретный день.
Вот как выглядит наш сценарий:
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");
После объединения всех данных результаты сохраняются в новой коллекции ежедневных отчетов. Давайте запустим сценарий и посмотрим, что мы получим:
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.
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 .