在 Mongodb 投影中使用 toString()

Use toString() in Mongodb projection

我不确定这是我面临的 MongoDB 问题还是其中一种工具(NoSQLBooster、Studio 3T)。我可以在 NoSQLBooster 中使用以下代码并且它有效。但是 Studio 3T 抱怨无效 JSON。我想我更喜欢 studio 3T,因为它似乎有更多的功能,是否有解决方法可以使这个有效 JSON?投影的 .toString() 部分有问题 "invalid JSON" (尽管这在 NoSQLBooster 中有效)。

$project:
    {
        _id: 0,
        "Country": "$country",
        "Zip From": {
            $cond: {
                if: { "$lt": [{ "$strLenCP": "$postcodeFrom" }, 4] },
                then: { $concat: ["0", "$postcodeFrom".toString()] },
                else: "$postcodeFrom".toString()
            }
        },
        "FRPUW": "0",
        "Estimated Delivery (days)": "$rate.serviceDeliveryDays"
    }

这里可以使用的是$substr or $substrBytes or $substrCP in modern versions. The first is considered deprecated in new releases and is "aliased" to $substrBytes。早就有把一个“integer/double”变成字符串的效果:

 { "$project": {
   "_id": 0,
   "Country": "$country",
   "Zip From": {
      "$cond": {
        "if": { "$lt": [{ "$strLenCP": { "$substr": ["$postcodeFrom",0,10] } }, 4] },
        "then": { "$concat": ["0", { "$substr": ["$postcodeFrom",0,10] }] },
        "else": { "$substr": ["$postcodeFrom", 0, 10 ] }
      }
   },
   "FRPUW": "0",
   "Estimated Delivery (days)": "$rate.serviceDeliveryDays"
 }}

从 MongoDB 4.0 开始,您可以使用 $toString alias to $convert 代替:

 { "$project": {
   "_id": 0,
   "Country": "$country",
   "Zip From": {
      "$cond": {
        "if": { "$lt": [{ "$strLenCP": { "$toString": "$postcodeFrom" } }, 4] },
        "then": { "$concat": ["0", { "$toString": "$postcodeFrom",0,10] }] },
        "else": { "$toString": "$postcodeFrom" }
      }
   },
   "FRPUW": "0",
   "Estimated Delivery (days)": "$rate.serviceDeliveryDays"
 }}

$substr 及其变体的唯一“问题”是您需要将最大字符串长度作为第三个参数。这可以是任何大于结果字符串预期长度的数字。这里我使用 10 作为合理的长度,但如果您希望得到更大的结果,请增加数字。

唯一需要注意的是,使用 $substr 不适用于其他类型。更“正式”的方法是 $toString,它涵盖了所有“类型”的大多数情况。实际的正式 $convert 实际上是针对预期的“类型转换”可能失败的情况,然后允许“错误处理程序”回退到返回默认值或其他“有效”表达式。

此外,作为“聚合表达式”,这些语句因此对任何实现语言都是“有效的”,而不仅仅是 JavaScipt,与主要误解相反,它实际上根本不是 MongoDB 的正式语言,除了在服务器评估的专门任务,无论如何都将逐渐弃用和删除。

NOTE - There is a little "misnomer" in the question where you quote "valid JSON". This is not actually about JSON but rather the fact that the aggregation framework only understands "valid expressions" and not "JavaScript Expressions" which you are attempting to use.

Contrary to a common misconception, when you see other code which includes a "JavaScript expression" within the content of an aggregation pipeline this code does not actually "execute on the server". What actually happens is the expression is evaluated "locally", then the result is translated to BSON and "that" is what is executed on the server.

Point in short is you cannot pass a "BSON field expression" into a "JavaScript function" or other local expression because that is not what actually happens when the statement is evaluated.