如何用MongoDB聚合与regex对集合字段做字符串操作统一价格单位
完全可以通过MongoDB聚合管道结合正则匹配实现该需求,具体实现方案如下:
实现思路
- 用正则提取
price字段中的数值部分和货币单位(gp/sp) - 将提取到的数值转为数字类型
- 按照
1GP = 10SP的规则换算,输出统一以GP为单位的标准价格字段,可直接用于后续的条件筛选、排序操作
代码实现(推荐正则版本,兼容性强)
该方案适配MongoDB 4.2及以上版本,支持大小写单位、数值与单位间多空格、小数价格等场景:
db.你的集合名称.aggregate([ { $addFields: { // 新增统一单位的标准价格字段 standard_price_gp: { $let: { vars: { // 正则分组提取:第1组为数值,第2组为单位 match_result: { $regexFind: { input: "$price", regex: /^(\d+\.?\d*)\s*(gp|sp)$/i } } }, in: { $cond: [ // 判断单位是否为sp { $eq: [ { $toLower: { $arrayElemAt: [ "$$match_result.captures", 1 ] } }, "sp" ] }, // sp转GP:数值除以10 { $divide: [ { $toDouble: { $arrayElemAt: [ "$$match_result.captures", 0 ] } }, 10 ] }, // gp直接转数值即可 { $toDouble: { $arrayElemAt: [ "$$match_result.captures", 0 ] } } ] } } } } }, // 示例:按价格从低到高排序 { $sort: { standard_price_gp: 1 } } ])
低版本兼容方案(MongoDB 4.2以下)
如果你的MongoDB版本不支持$regexFind,且price字段格式严格为「数值+空格+单位」,可以用$split拆分字符串实现,性能更高:
db.你的集合名称.aggregate([ { $addFields: { // 拆分价格为[数值, 单位]数组 price_parts: { $split: [ { $trim: { input: "$price" } }, " " ] } } }, { $addFields: { standard_price_gp: { $cond: [ { $eq: [ { $toLower: { $arrayElemAt: [ "$price_parts", 1 ] } }, "sp" ] }, { $divide: [ { $toDouble: { $arrayElemAt: [ "$price_parts", 0 ] } }, 10 ] }, { $toDouble: { $arrayElemAt: [ "$price_parts", 0 ] } } ] } } }, // 移除临时字段 { $unset: "price_parts" } ])
转换后的standard_price_gp为标准数值类型,可直接用于条件筛选,比如筛选价格低于2GP的文档,只需新增$match阶段:
{ $match: { standard_price_gp: { $lt: 2 } } }
系统会自动识别10 sp换算后为1GP,正确匹配筛选条件。
内容的提问来源于stack exchange,提问作者Kirk_
相关产品推荐
相关产品推荐

