使用 MongoDB 聚合框架四舍五入到小数点后两位

问题描述:

我正在使用 mongodb 聚合框架并进行一些计算,如下所示

I am using the mongodb aggregation framework and doing some calculations as shown below

db.RptAgg.aggregate( 
  {$group: {
    _id: {Region: "$RegionTxt", Mth: "$Month"},           
    ActSls: {$sum:"$ActSls"},
    PlnSls: {$sum:"$PlnSls"}
  }},
  {$project: {
    ActSls: 1,
    PlnSls: 1,
    ActToPln: {$cond: [
      {$ne: ["$PlnSls", 0]}, 
      {$multiply: [{$divide: ['$ActSls', '$PlnSls']}, 100]}, 
      0
    ]}
  }}
); 

我正在尝试找出将结果四舍五入到小数点后两位的最佳和最简单的方法.以下是我的结果

I am trying to figure out what is the best and easiest way to round my results to 2 decimal places. Following is my result

{
  "result": [{
    "_id": {
      "Region": "East",
      "Mth": 201301
    },
    "ActSls": 72,
    "PlnSls": 102,
    "ActToPln": 70.58823529411765
  }],
  "ok": 1
}

我想要ActToPln"显示 70.59 而不是 ActToPln";: 70.58823529411765,在聚合框架本身的结果中.我想避免在我的应用程序中进行四舍五入

I want "ActToPln" to show 70.59 instead of "ActToPln" : 70.58823529411765, in the results from aggegation framework itself. I want to avoid doing the rounding in my application

你能帮忙吗.

以下是我使用的数据集.

Following is the dataset i used.

{
    "_id" : ObjectId("51d67ef69557c507cb172572"),
    "RegionTxt" : "East",
    "Month" : 201301,
    "Date" : "2013-01-01",
    "ActSls" : 31,
    "PlnSls" : 51
}
{
    "_id" : ObjectId("51d67ef69557c507cb172573"),
    "RegionTxt" : "East",
    "Month" : 201301,
    "Date" : "2013-01-02",
    "ActSls" : 41,
    "PlnSls" : 51
}

提前致谢.南都

没有 $round 运算符,但您可以在聚合框架中执行此操作 - 按特定顺序执行通常会避免浮点精度问题.

There is no $round operator but you can do this in the aggregation framework - doing it in specific order will usually avoid floating point precision issues.

> db.a.save({x:1.23456789})
> db.a.save({x:9.87654321})
> db.a.aggregate([{$project:{ _id:0, 
         y:{$divide:[
              {$subtract:[
                      {$multiply:['$x',100]},
                      {$mod:[{$multiply:['$x',100]}, 1]}
              ]},
              100]}
}}])
{ "y" : 1.23 }
{ "y" : 9.87 }

给定问题中现有的管道,替换:

Given the existing pipeline in the problem, replace:

{$multiply:[{$divide: ['$ActSls', '$PlnSls']},100]}

{$divide:[
     {$subtract:[ 
          {$multiply:[
             {$divide: ['$ActSls','$PlnSls']},
             10000
          ]}, 
          {$mod:[
             {$multiply:[{$divide: ['$ActSls','$PlnSls']}, 10000 ]},
             1]}
          ]}, 
     100
]}

使用您的样本数据点,结果如下:

With your sample data points this is the result:

{ "ActSls" : 31, "PlnSls" : 51, "ActToPln" : 60.78 }
{ "ActSls" : 41, "PlnSls" : 51, "ActToPln" : 80.39 }
{ "ActSls" : 72, "PlnSls" : 102, "ActToPln" : 70.58 }