У меня есть несколько документов, сохраняемых в Mongodb со структурой, такой как:
{
Time: "2019-04-18 23:59:59" ,
Cat1:{
sub_cat1:{server1:{"prop":2},server2:{"prop":4},server3:{"prop":1}},
sub_cat2:{server1:{"prop":1},server2:{"prop":3},server3:{"prop":2}},
sub_cat3:{server1:{"prop":2},server2:{"prop":1}},
sub_cat4:{server2:{"prop":5},server3:{"prop":1}}
}
},
Time: "2019-04-18 23:58:59" ,
Cat1:{
sub_cat1:{server1:{"prop":2},server2:{"prop":2},server3:{"prop":1}},
sub_cat2:{server1:{"prop":3},server2:{"prop":2},server3:{"prop":1}},
sub_cat3:{server1:{"prop":3},server2:{"prop":4}},
sub_cat4:{server2:{"prop":1},server3:{"prop":2}}
}
}
, и данные сохраняются каждую минуту.
Я хочу получить ежедневную последнюю суммированную сумму для всехsub_cat1 для каждого сервера.И предположим, что всего есть 3 сервера, но не у каждого документа есть 3 сервера, потому что не у каждого сервера есть подкатегория *.
И предположим, что я хочу получить данные за период с 2019-4-16 до 2019-4-18, затем я хочу получить такой результат,
{server1:{"2019-04-16":{"Time":"2019-04-16 23:59:59","prop":10},
"2019-04-17":{"Time":"2019-04-17 23:58:59","prop":8},
"2019-04-18":{"Time":"2019-04-18 23:59:59","prop":5}},
server2: {"2019-04-16":{"Time":"2019-04-16 23:50:59","prop":6},
"2019-04-17":{"Time":"2019-04-17 23:52:59","prop":9},
"2019-04-18":{"Time":"2019-04-18 23:59:59","prop":13}},
server3:{"2019-04-16":{"Time":"2019-04-16 23:53:59","prop":4},
"2019-04-17":{"Time":"2019-04-17 23:56:59","prop":6},
"2019-04-18":{"Time":"2019-04-18 23:59:59","prop":4}} }
, но результат, похоже, возвращает только последний документ для каждого сервера вместо ежедневного последнего документа для каждого сервера.
Код редукции карты, который я использую, выглядит следующим образом:
var map = function(){
final_result = {};
cats= ["cat1"];
for(var cat of cats)
{
if(cat in this)
{
for(var sub_cat in this.cat)
{
for(var server in this.cat.sub_cat)
{
if (!(server in final_result))
{
final_result[server] = {"Time":this.Time,"prop":0}
}
final_result[server]["prop"]+=this.cat.sub_cat.server.prop;
}
} ;
}
}
var key = this["Time"].toISOString().split('T')[0];
if( final_result.length!=0 )
{
for(var server in final_result)
{
emit(server, {key: final_result[server]});
}
}
};
var reduce = function(key,values){
var result ={};
for(var idx=0; idx< values.length;idx++)
{
for(var time in values[idx])
{
if(!(time in result))
{
result[time] = values[idx][time];
}
result[time] = values[idx][time].Time>result[time].Time ? values[idx][time]:result[time] ;
}
}
return result;
};
db.getCollection('collection_name').mapReduce(
map,
reduce,
{
out:{inline:1} ,
query:{Time:{$gte: new ISODate("2019-04-16"), $lte:new ISODate("2019-04-19")}},
sort:{Time:-1}
}
)
Я знаю, что функция редукции должна возвращать значение с той же структурой, что и у суб-содержимого функции карты, но для моей функции карты, суб-функции-контент как
{"2019-04-16":{"Time":"2019-04-16 23:59:59","prop":10}}
И я просто хочу получить вывод из функции сокращения, например:
{"2019-04-16":{"Time":"2019-04-16 23:59:59","prop":10},
"2019-04-17":{"Time":"2019-04-16 23:59:59","prop":10},
"2019-04-18":{"Time":"2019-04-16 23:59:59","prop":10}}
Почему это не применимо?И если кто-нибудь знает лучшее решение, чем мой код, пожалуйста, дайте мне знать, я был бы очень признателен за любую помощь от вас.