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

时间:2016-02-03 15:12:34

标签: javascript mongodb mongoose underscore.js

我使用mongoose find()方法从db获取所有记录。之后我想创建新的排序数组或对象数组。这些记录可以具有相同的参数名称,如"startNum"。如何将具有相同参数的总和值和每个的平均值计算在一起?

我尝试使用Javascript for循环,但我只有db的这个结果值的数组有相同的"startNum"参数,但是很少有空格我不想要 - 就像{{1 }}。我认为这可以更轻松。如果是使用underscorejs制作它会很好。

这是我的尝试:

[2, , ,5]

我知道这种排序Underscore方法,这可能很有用,但不知道如何做到这一点。

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);
                }
              }
              }// ..

总结一下,我想计算每个var sorted = _.sortBy(a, function(num) { return num; }); 类别的平均值。例如对象数组

第一个对象

startingNum

那些猫鼬结果如下:

{
    startingNum: 1,
counted_Average_Of_All_Existing_In_DataBase_Categories_From_One_To_Five_For_startingNum1: value
}

我认为使用[ { categoryFive: 1, categoryFour: 1, categoryThree: 1, categoryTwo: 1, categoryOne: 1, startingNumber: 1},... ] 会好得多。有人可以帮忙吗?我无法弄清楚如何做对。

2 个答案:

答案 0 :(得分:2)

我看到你已经编写了javascript循环代码,通过startingNumber对文档进行分组,然后对类别值求和,你只想输入如何使用underscore.js对其进行排序。

但是,我相信使用MongoDB的聚合框架为您进行分组,求和和排序会更好更简单。您还说过想要计算平均值,所以我的示例代码也计算了计数和平均值。

如果我加载您的样本数据:

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}
]) ;

然后这句话:

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}}
]);

生成此输出:

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

答案 1 :(得分:1)

我假设你想要找到按起始编号分组的所有类别的总分。如果是这样,请使用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();