Как вернуть несколько элементов в объекте в MongoDB MapReduce - PullRequest
0 голосов
/ 19 апреля 2019

У меня есть несколько документов, сохраняемых в 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}}

Почему это не применимо?И если кто-нибудь знает лучшее решение, чем мой код, пожалуйста, дайте мне знать, я был бы очень признателен за любую помощь от вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...