MongoDb - 管道帮助 $trunc

MongoDb - Help for pipeline with $trunc

我的数据:

[
    { total: 7421356 }, 
    { total: 79421356 },
    { total: 105457854 },
    { total: 1054578540 },
    { total: 10545785400 },
]

我想要类似的东西:

[
    { val: 7000000, count 1 },
    { val: 70000000, count 1 },
    { val: 100000000, count: 1 },
    { val: 1000000000, count 1 }
]

实际上我用的是这条管道:

{
    $addFields: {
        length: {
            $multiply: [
                {
                    $add: [
                        {
                            $strLenCP: {
                                $toString: "$val",
                            }
                        },
                        -1
                    ]
                },
                -1
            ]
        },
    },
},
{
    $project: {
        value: {
            $trunc: ["$val", "$length"],
        },
        _id: 0,
    }
},
{
    $group: {
        _id: "$value",
        count: {
            $sum: 1
        }
    }
}, 
{
    $project: {
        value: "$_id",
        count: 1, 
        _id: 0,
    }
},
{
    $sort: {
        value: 1
    }
}

当我有像“10545785400”这样的数据时,我遇到了问题。 看起来他的长度太长了,对于我的数据“7421356”,他的结果现在是“0”。

我以为文件是单独通过管道的,但似乎不是。 我的第一个数据似乎使用了我最后一个的长度。

虽然我的解释不是很清楚,但我希望有人能帮助我。

编辑:这似乎是一个“类型”问题。大于 1.000.000.000 的数据是 double 而不是 int32 编辑 2:它适用于“24760000000”但不适用于“25661674539”。我真的不明白为什么。它们以 Double 格式存储。

tl;博士

  • 添加 $toLong:"$total" (from here)

正在将双精度转换为科学记数法,并且考虑到测量字符串长度,在大多数或所有字段中为 9。正如你所说,这些数字的类型是双精度的。

See a working example here,在截断数据之前将字符串转换为数字:

db.collection.aggregate({
  $addFields: {
    length: {
      $multiply: [
        {
          $add: [
            {
              $strLenCP: {
                $toString: {
                  $toLong: "$total"
                },
                
              }
            },
            -2
          ]
        },
        -1
      ]
    },
    
  }
},
{
  $project: {
    value: {
      $toLong:{
        $trunc: [
        "$total",
        "$length"
      ],
      }
    },
    _id: 0,
    
  }
})

详情

  • 您不能使用 $toInt 将这些大数字转换为 int,因为这些数字很大。大大于 10^10