对 mongodb collection 中的字段进行字符串操作(聚合和正则表达式)

Make string operations on field in mongodb collection (Aggregation & regex)

我在 Mongo 中使用 collection,价格字段有多种货币类型:

{
  price: '15 gp' // 15 gold pieces
}

{
  price: '4 sp' // 0.4 gold pieces
}

我正在寻找一种在查询 collection 之前修改此字段的方法。

例如,修改字符串以删除 gp/sp 并进行数学运算以获得“GP”中的正确价格(1 GP = 10 SP)

这将有助于订购 collection,因为 mongo 无法理解 10 sp < 2 gp。

有没有办法使用聚合和正则表达式来做到这一点?

首先添加新字段 rate 并检查 gp 或 sp 以及每个价格的看跌利率,例如 sp 的利率为 10,gp 的利率为 1 然后添加 universalprice 字段,乘以价格率和价格值 之后你可以比较价格

db.collection.aggregate([
  {
    "$addFields": {
      "newField": {
        "$split": [
          "$price",
          ","
        ]
      }
    }
  },
  {
    "$project": {
      price: {
        $reduce: {
          input: "$newField",
          initialValue: "",
          in: {
            $concat: [
              "$$value",
              "$$this"
            ]
          }
        }
      }
    }
  },
  {
    "$addFields": {
      "rate": {
        "$switch": {
          "branches": [
            {
              "case": {
                "$regexMatch": {
                  "input": "$price",
                  "regex": ".*gp*."
                }
              },
              "then": "1"
            },
            {
              "case": {
                "$regexMatch": {
                  "input": "$price",
                  "regex": ".*sp*."
                }
              },
              "then": "10"
            }
          ],
          default: 1
        }
      }
    }
  },
  {
    "$project": {
      price: 1,
      universalPrice: {
        "$multiply": [
          {
            "$toInt": "$rate"
          },
          {
            "$toInt": {
              $first: {
                "$split": [
                  "$price",
                  " "
                ]
              }
            }
          }
        ]
      }
    }
  }
])

https://mongoplayground.net/p/S5EIUdWRp5W

您可以使用此聚合阶段来转换 price 字段值:

db.collection.aggregate([
  { 
      $addFields: { 
          price: {
              $function: {
                  body: function(inPrice) {
                               let outPrice;
                               if (/gp/.test(inPrice)) {
                                   outPrice = parseInt(inPrice.replace("gp", "").trim()) * 10;
                               }
                               else if (/sp/.test(inPrice)) {
                                   outPrice = parseInt(inPrice.replace("sp", "").trim());
                               }
                               else {
                                   outPrice = inPrice; // whatever needs here...
                               }
                               return outPrice;
                  },
                  args: [ "$price" ],
                  lang: "js"
              }
          }
      }
  }
])

例如,price: "5 gp" 将转换为 price: 50 并且 price: "12 sp" 将转换为 price: 12。请注意,这些值将转换为数字类型字段以进行比较和计算。