Meteor + Mongo平均计数

时间:2016-12-19 15:18:39

标签: javascript mongodb algorithm math meteor

我们说我有这样的文件

{
    "_id" : "PQ8GUYYB7IERPNE9NX-CombQQD7F",
    "combId" : 5,
    "alignToOffer" : true,
    "product" : "TwBuYJZquKeKTmtwr",
    "price" : 85,
}

现在我想让相同产品的每个组合的平均值对齐(如果它被检查对齐),那么我正在使用流星观察手柄来做到这一点。并在相关文件的每次更改中获得汇总的平均价格值

Offers.find({}).observe({
   changed: function(offer, fields) {

      var result = Offers.aggregate(
          [
             {
                $match:
                {
                   product: offer.product,
                   status: true,
                   combId: Number(offer.combId)
                }
             },
             {
                $group:
                {
                   _id: "$product",
                   priceAlign: { $avg: "$price" },
                   minPrice: { $min: "$price" }
                }
             }
          ]
      );

      if ( result.length ){
         var averageValue = parseFloat(Math.round(result[0].priceAlign * 100) / 100).toFixed(2),
         bestOffer = parseFloat(Math.round(result[0].minPrice * 100) / 100).toFixed(2);
         var updateValues = { $set: {
            avgOffer: averageValue,
            bestOffer: bestOffer
         }};

         var updatePrice = { $set: {
            price : averageValue
         }};

         Offers.update({
            product: offer.product,
            combId: offer.combId,
            status: true
         }, updateValues, {multi: true});

         Offers.update({
            product: offer.product,
            combId: offer.combId,
            alignToOffer: true,
            status: true
         }, updatePrice, {multi: true});
      }
   }
});

它的工作完美,有一个真正的问题是节省平均价格。得出结论我有三个相同产品的文件,其中两个对齐(对齐提供密钥检查)而一个不是,现在当我更改固定值doc价格(未对齐)时,其他两个将保存{{ 1}}或+1(带小数位)不是相同的价格,即如果我使用-1保存固定价格,则另一个价格为9695.99999999999996不是96.00000000000001。我需要一个完整的数字,但当我用任何香草JS的方法删除十进制值。例如96它会给我少1或更多的价值。我从晚上开始在PC上摸不着头脑。任何帮助将不胜感激。

上次更改已向我toFixed()96.01

1 个答案:

答案 0 :(得分:2)

你不需要为计算平均值添加额外的逻辑。
只需按照以下步骤操作或使用mongoDB $avg运算符。

1)在您的情况下,首先获得所有包含alignToOffer: false的文档。

2)使用aggregation计算平均值后。 或者手动计算如下。

3)在alignToOffer: true简单的文档中设置。

1)

let result = Offers.find({ product: offer.product, status: true, alignToOffer: false, combId: Number(offer.combId) }).fetch(); //fetch for meteor.

2)

// if get only one document then set it's price no need to calculate avg let avg = result.length > 1 ? result.map(obj => obj.price).reduce((o,n) => o + n) / result.length : result[0].price;

3)

Offers.update({ product: offer.product, alignToOffer: true, status: true, combId: Number(offer.combId) }, {$set:{ price : Number(avg) }}, { multi: true });