27

私はmongodb集約フレームワークを使用しており、以下に示すようにいくつかの計算を行っています

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

結果を小数点以下 2 桁に丸める最も簡単な方法を見つけようとしています。以下は私の結果です

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

集計フレームワーク自体の結果で、"ActToPln" : 70.58823529411765の代わりに"ActToPln" が70.59 を表示するようにします。アプリケーションで丸めを回避したい

同じことを手伝ってもらえますか。

以下は、私が使用したデータセットです。

{
    "_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
}

前もって感謝します。ナンドゥ

4

10 に答える 10

19

演算子はありません$roundが、集計フレームワークでこれを行うことができます。特定の順序で行うと、通常、浮動小数点の精度の問題を回避できます。

> 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 }

問題の既存のパイプラインを考慮して、以下を置き換えます。

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

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

サンプル データ ポイントを使用すると、次の結果が得られます。

{ "ActSls" : 31, "PlnSls" : 51, "ActToPln" : 60.78 }
{ "ActSls" : 41, "PlnSls" : 51, "ActToPln" : 80.39 }
{ "ActSls" : 72, "PlnSls" : 102, "ActToPln" : 70.58 }
于 2014-03-22T12:33:51.197 に答える
0

Watch out for issues with the $round aggregation. When working with double type will sometimes round incorrectly. Here is an example:

5.885 --to double--> 5.8849999999999 ---$round(2)--> 5.88 (instead of 5.89)

Here is a workaround:

> db.a.save({x:5.884})
> db.a.save({x:5.885})
> db.a.save({x:5.886})
> db.a.aggregate([{
     $project:{
         _id:0, 
         x: '$x',
         round: {$round: ['$x', 2]}
         better_round: {$round: [{$add: ['$x', 0.000000001]}, 2]}
     }
}])
Output:
{ "x" : 5.884, "round" : 5.88, "better_round" : 5.88 }
{ "x" : 5.885, "round" : 5.88, "better_round" : 5.89 }
{ "x" : 5.886, "round" : 5.89, "better_round" : 5.89 }
于 2022-02-09T11:45:48.243 に答える