mongoose 如何在MongoDB上舍入小数而不使用Decimal128类型

r55awzrz  于 2023-10-19  发布在  Go
关注(0)|答案(2)|浏览(162)

我有一个关于十进制支持的问题。我想使用小数,我知道Mongo建议使用Decimal128类型。它解决了db上的舍入格式,但另一方面,我需要在获取数据时将十进制(BSON)写入数字转换器的getter。
我想在不改变数据类型的情况下使用小数。我在批量操作中经常使用mongoose的$inc,$dec操作符。如果我继续使用Number(mongoose上的Number,Mongo上的Double)类型,我可以看到很长的小数结尾的一些操作。例如,如果I $inc 2.4与1.2的结果将是3.599999999999996(浮点数问题)。
有没有一种方法可以让Mongo通过mongoose模型或直接在db上以某种方式将选定字段的“最终值”四舍五入到max 2?setter不工作,因为2.4或1.2没有问题,问题是inc操作的结果。或者柱子挂钩不适用于散装货。
先谢了。

dxxyhpgq

dxxyhpgq2#

我用change streamers解决了这个问题。我在对特定集合执行任何插入或更新操作后检查发布数据。如果有一个值与我的长数字十进制模式相匹配,则更新为四舍五入版本。

const FORMAT_NEEDED_DECIMAL_REGEX = /^\d+\.\d{3,}$/;
const DECIMAL_ROUNDING_PLACE = 2;

const config = [[{
  $match: { operationType: { $in: ['insert', 'update'] } },
}], {
  fullDocument: 'updateLookup',
}];

const yourModelStream = YourModel.watch(...config);

yourModelStream.on('change', (postData) => {
  const { documentKey: { _id: id }, updateDescription, operationType, fullDocument } = postData;

  const document = operationType === 'update' ? updateDescription.updatedFields : fullDocument;

  const updateQuery = Object.keys(document).reduce((acc, field) => {
    if (FORMAT_NEEDED_DECIMAL_REGEX.test(document[field])) {
      return { ...acc, [field]: { $round: [`$${field}`, DECIMAL_ROUNDING_PLACE] } };
    }
    return acc;
  }, {});

  if (Object.keys(updateQuery).length) {
    YourModel.updateOne({ _id: id }, [{ $set: updateQuery }]).exec().catch(() => undefined);
  }
});

相关问题