You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中MongoDB的Int32类型price无法转千分位字符串怎么办?

问题:MongoDB返回的Int32类型price字段无法转换为千分位字符串

问题场景

从MongoDB拉取hotAsset: true的Asset集合数据,price字段为Int32类型:

const hotAssets = await Asset.find({ hotAsset: true });

将数组传入工具函数试图把price转为带千分位的字符串,但修改始终不生效:

函数调用:

Utils.assetPriceToString(hotAssets);

函数实现:

exports.assetPriceToString = (assetsArray) => {
  for (const asset of assetsArray) {
    if (asset.price) asset.price = asset.price.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
  }
};

集合数据示例:

{
    location: {
      coordinates: [Array],
      title: 'Central Park Burgas',
      type: 'Point'
    },
    _id: new ObjectId('66420dbd1ada8e8e709e30a7'),
    id: 3698,
    name: 'new flat',
    slug: 'new-flat',
    price: 120000,
    project: 'Central Park Burgas',
    city: 'Burgas',
    type: 'דירה',
    sm: '82 מ"ר',
    oceanView: '',
    rooms: '2',
    bathrooms: 1,
    terraces: '1',
    floor: '18 מ 20',
    readiness: '',
    serviceTax: '',
    description: 'some descriptin', 
    year: 2008,
    mainImage: '/img/asset1.jpg',
    images: [
      '/img/asset1.jpg',  '/img/asset2.jpg',
      '/img/asset3.jpg',  '/img/asset4.jpg',
      '/img/asset5.jpg',  '/img/asset6.jpg',
      '/img/asset7.jpg',  '/img/asset8.jpg',
      '/img/asset9.jpg',  '/img/asset10.jpg',
      '/img/asset11.jpg', '/img/asset12.jpg',
      '/img/asset13.jpg', '/img/asset14.jpg',
      '/img/asset15.jpg', '/img/asset16.jpg',
      '/img/asset17.jpg', '/img/asset18.jpg',
      '/img/asset19.jpg', '/img/asset20.jpg',
      '/img/asset21.jpg', '/img/asset22.jpg',
      '/img/asset23.jpg'
    ],
    hotAsset: true,
    updated_at: 2024-05-13T12:55:24.545Z,
    __v: 0,
    priceNis: 482027
  }

测试发现:硬编码的普通JS对象数组转换正常,但MongoDB返回的price字段,用toString()、String()、Intl.NumberFormat.format()等方法转换后,控制台打印看似是字符串,实际赋值后未生效。


原因分析

MongoDB驱动(Mongoose)返回的文档是不可变的Mongoose Document对象,而非普通JavaScript对象。Document对象内置了类型校验和属性拦截机制,会强制保持字段的原始数据类型(这里是Int32)。即使你赋值了字符串,它会自动转回Int32类型,导致修改无效。


解决方案

方案1:拉取数据时直接转为普通JS对象

在查询时添加.lean()方法,跳过Mongoose的Document包装,直接获取普通JS对象:

const hotAssets = await Asset.find({ hotAsset: true }).lean();

之后再调用Utils.assetPriceToString(hotAssets),就能正常修改price字段。

方案2:在工具函数内转换单个Document

如果不想全局使用.lean(),可以在函数内将每个Asset Document转为普通对象:

exports.assetPriceToString = (assetsArray) => {
  return assetsArray.map(asset => {
    // 转为普通JS对象
    const plainAsset = asset.toObject();
    if (plainAsset.price) {
      // 用正则或Intl.NumberFormat转换千分位
      plainAsset.price = new Intl.NumberFormat().format(plainAsset.price);
    }
    return plainAsset;
  });
};

调用时接收返回的修改后数组:

const formattedHotAssets = Utils.assetPriceToString(hotAssets);

方案3:用Intl.NumberFormat替代正则(更优雅)

不管用哪种方式转换对象,都推荐用Intl.NumberFormat替代手动正则,它支持多语言环境,代码更简洁:

// 转换逻辑替换为:
plainAsset.price = new Intl.NumberFormat().format(plainAsset.price);

比如输入120000会直接得到"120,000"。


内容的提问来源于stack exchange,提问作者Dror Salomon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 02:14:56