Автор оригинала: 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 .