简体   繁体   English

如何按每个id对数组中的对象求和,计算平均和,按条件顺序设置

[英]How to sum objects in array by each id, count average sum, set in order with condition

I am using mongoose find() method to get all records from db. 我正在使用mongoose find()方法从db获取所有记录。 After that I want to create new sorted array or array of objects. 之后我想创建新的排序数组或对象数组。 Those record can have same parameter name like "startNum" . 那些记录可以具有相同的参数名称,如"startNum" How can I have summed values with same parameter and counted average value of each? 如何将具有相同参数的总和值和每个的平均值计算在一起?

I tried using Javascript for loops but I have got only arrays with this result values from db with this same "startNum" parameter, but few of them have empty spaces that I don't want - it's like [2, , ,5] . 我尝试使用Javascript for循环,但我只有db的这个结果值的数组与这个相同的"startNum"参数,但很少有空格我不想要 - 它就像[2, , ,5] "startNum" [2, , ,5] I think it can be done easier. 我认为这可以更轻松。 It would be nice if it was made using underscorejs. 如果是使用underscorejs制作它会很好。

Here is my try: 这是我的尝试:

stars.find({}, function(error, result) {
               if(error) {
                 console.log(error);
               }
               var tmp = {};
               var a = [];
               One = {};
               var snOne = [];
               Two = {};
               var snTwo = [];
               Three = {};
               var snThree = [];
               var Four = {};
               var snFour = [];
               var Five = {};
               var snFive = [];

              for (var s = 0; s < result.length; s ++) {
                if (result[s].startingNumber === 1) {
                  snOne[0] = 1; // numer startowy konia
                  snOne[s+1]=(result[s].categoryOne + result[s].categoryTwo + result[s].categoryThree + result[s].categoryFour + result[s].categoryFive);
                }


                 if (result[s].startingNumber === 2) {
                  for (var q = 0; q < result.length; q ++) {
                  snTwo[0] = 2;
                  snTwo[q+1]=(result[q].categoryOne + result[q].categoryTwo + result[q].categoryThree + result[q].categoryFour + result[q].categoryFive);
                  }
                }

              for (var w = 0; w < result.length; w ++) {
                 if (result[w].startingNumber === 3) {
                  snThree[0] = 3;
                  snThree[w+1]=(result[w].categoryOne + result[w].categoryTwo + result[w].categoryThree + result[w].categoryFour + result[w].categoryFive);
                }
              }
                for (var e = 0; e < result.length; e ++) {
                 if (result[e].startingNumber === 4) {
                  snFour[0] = 4;
                  snFour[e+1]=(result[e].categoryOne + result[e].categoryTwo + result[e].categoryThree + result[e].categoryFour + result[e].categoryFive);
                }
              }
                for (var r = 0; r < result.length; r ++) {
                 if (result[r].startingNumber === 5) {
                  snFive[0] = 5;
                  snFive[r+1]=(result[r].categoryOne + result[r].categoryTwo + result[r].categoryThree + result[r].categoryFour + result[r].categoryFive);
                }
              }
              }// ..

I know this sorting Underscore method, that can be useful, but dont know exactly how to do this. 我知道这种排序Underscore方法,这可能很有用,但不知道如何做到这一点。

var sorted = _.sortBy(a, function(num) { return num; });

To sum up I want to have counted average value for each startingNum category. 总结一下,我想计算每个startingNum类别的平均值。 For example array of objects 例如对象数组

first object 第一个对象

{
    startingNum: 1,
counted_Average_Of_All_Existing_In_DataBase_Categories_From_One_To_Five_For_startingNum1: value
}

Those mongoose results looks like: 那些猫鼬结果如下:

[ {
categoryFive: 1,
categoryFour: 1,
categoryThree: 1,
categoryTwo: 1,
categoryOne: 1,
startingNumber: 1},... ]

I think it would be much better using underscorejs . 我认为使用underscorejs会好得多。 Can someone help? 有人可以帮忙吗? I can't figure out how to make it right. 我无法弄清楚如何使它正确。

I see you have already written javascript loop code to group your documents by startingNumber and then sum the category values, and you just wanted input on how best to sort that using underscore.js. 我看到你已经编写了javascript循环代码,通过startingNumber对文档进行分组,然后对类别值求和,你只想输入如何使用underscore.js对其进行排序。

However, I believe it would be better and simpler to use MongoDB's aggregation framework to do the grouping, summing and sorting for you. 但是,我相信使用MongoDB的聚合框架为您进行分组,求和和排序会更好更简单。 You had also said you wanted a counted average so my sample code calculates count and average too. 您还说过您想要计算平均值,因此我的示例代码也会计算计数和平均值。

If I load your sample data: 如果我加载您的示例数据:

db.catdata.insert([
  {categoryFive:   1, categoryFour:   1, categoryThree:   1, 
   categoryTwo:    1, categoryOne:    1, startingNumber:  1},
  {categoryFive:   2, categoryFour:   1, categoryThree:   2, 
   categoryTwo:    1, categoryOne:    2, startingNumber:  1},
  {categoryFive:   1, categoryFour:   1, categoryThree:   1, 
   categoryTwo:    1, categoryOne:    1, startingNumber:  2},
  {categoryFive:  20, categoryFour:   1, categoryThree:  20, 
   categoryTwo:   20, categoryOne:   20, startingNumber:  1},
  {categoryFive: 100, categoryFour: 100, categoryThree: 100, 
   categoryTwo:  100, categoryOne:  100, startingNumber:  2}
]) ;

then this statement: 那么这句话:

db.catdata.aggregate([
    {"$project" : {"startingNumber":1,
           "cats1to5":{$add:["$categoryFive", "$categoryFour", 
           "$categoryThree", "$categoryTwo",  "$categoryOne"]}
                  }
    }
   ,{"$group": {"_id"  : "$startingNumber",  "cntCat":{$sum:1},
                "totCat":{$sum:"$cats1to5"}, "avgCat":{$avg:"$cats1to5"}
               }
    }
   ,{$sort : {startingNumber:1}}
]);

produces this output: 产生这个输出:

{ "_id" : 2, "cntCat" : 2, "totCat" : 505, "avgCat" : 252.5 }
{ "_id" : 1, "cntCat" : 3, "totCat" : 94, "avgCat" : 31.333333333333332 }

I'm assuming you wanted to find the total score across all categories grouped by the starting number. 我假设您想要找到按起始编号分组的所有类别的总分。 If so, here goes the solution using underscore.js 如果是这样,这里使用underscore.js解决方案

// group by startingNumber
// each group will have multiple objects denoted by 'objs'
var grouped = _.chain(data).groupBy('startingNumber').map(function (objs, startNum) {
    // iterate through the objects for the current starting number
    var score = _.chain(objs).map(function (obj) {
        // remove all keys which are not starting with category
        var obj    = _.pick(obj, function (value, key) {
            return key.indexOf('category') !== -1;
        });
        var scores = _.values(obj); // get the scores for each category

        // compute the sum across all categories for this object
        return _.reduce(scores, function (memo, categoryScore) {
            return memo + categoryScore;
        }, 0);
        // compute the sum across all objects for this group
    }).reduce(function (memo, value) {
        return memo + value;
    }, 0).value();

    return {
        start: startNum,
        score: score
    };
}).value();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM