У меня есть скрипт в mongoshell, который должен заполнить коллекцию (dataaggregation) из другой (данные), объединив таймеры на каждые 5 минут.
Сбор данных имеет 7.000.000+ записей, и сценарий занимает много времени, чтобы завершить ... 8 часов за 500 000 данных, которые необходимо учитывать и теперь кажется замороженным.Не удается запустить скрипт оболочки mongo на несколько миллионов данных
В основном сбор данных содержит записи, как:
{
isodate: '2014-12-1OT12:47:32.000+02.00',
value: 234,
parentID: 123
}
Коллекция dataaggreagtion содержит записи, как:
{
t: '2014-12-1OT12:45:00.000+02.00',
pid: 123, // parentID
sum: 1234, // sum of all the value of data between 12:45 and 12:50
count: 5, // number of data elements between 12:45 and 12:50
min: 23,
max: 435
}
Каждая запись сбора данных будет являться частью записи о dataaggregation коллекция (будет считаться 1 в атрибуте count).
// Cleanup collection
db.dataaggregation.remove({})
// Loop through data and populate the dataaggregation collection
db.data.find().addOption(DBQuery.Option.noTimeout).forEach(function(dt){
// Get 5 minutes timestamp
// eg: '2014-12-1OT12:47:32.000+02.00' => '2014-12-1OT12:45:00.000+02.00'
dt.isodate.setMinutes(dt.isodate.getMinutes() - dt.isodate.getMinutes() % 5);
dt.isodate.setSeconds(0);
// Create the dataaggregation record for the (timestamp, parentID) couple if does
// not exist or update the existing one
var d = db.dataaggregation.findOne({t: dt.isodate, pid: dt.parentID});
if(!d){
db.dataaggregation.insert({
t:dt.isodate,
pid: dt.parentID,
sum: dt.value,
count: 1,
min: dt.value,
max: dt.value
});
}else{
db.dataaggregation.update({
t:dt.isodate,
pid: dt.parentID
},{
$set:{
sum: d.sum + dt.value,
count: d.count + 1,
min: dt.value < d.min ? dt.value : d.min,
max: dt.value > d.max ? dt.value : d.max
}
},
{upsert:true}
);
}
})
Любая идея или предложение улучшить это? Есть ли что-то очевидное, что мне не хватает?
Спасибо, как бы вы группировать временные метки, так что каждый данные идут в правильном 5 минут ведро? Например, 2014-12-1OT12: 47: 32.000 + 02.00 должны перейти в dataaggregation, на которые ссылаются: 1. тот же самый родительский идентификатор, что и исходная запись данных; 2. следующая временная метка 2014-12-1OT12: 45: 00.000 + 02.00 – Luc
@Luc Это можно сделать довольно легко с помощью агрегации. Но со всей справедливостью это не вопрос, который вы задали здесь. Если у вас есть другой вопрос, тогда лучше задать другой вопрос. Я делаю ваше намерение понятным для каждого вопроса, и, как правило, модель StackExchange является «единственным вопросом только для каждого ответа». Сводка по математике или дате даты - это подсказка. Если вы не можете понять это, тогда задайте другой вопрос. На этот ответ был дан ответ, пока агрегация подходит для использования, а не для кодированного ответа клиента. –
Это была скрытая часть моего вопроса (это было в комментарии к коду), но вы правы. Я не был таким ясным, хотя :) – Luc