$convert(聚合)
定义
兼容性
可以使用 $convert
查找托管在以下环境中的部署:
MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
语法
$convert
通过以下语法实现:
{ $convert: { input: <expression>, to: <type expression>, onError: <expression>, // Optional. onNull: <expression> // Optional. } }
$convert
接受包含以下字段的文档:
字段 | 说明 | |||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
input | ||||||||||||||||||||||||||||
to | 参数可以是任何有效表达式,并能解析为下列数字或字符串标识符之一:
| |||||||||||||||||||||||||||
onError | 可选。转换期间出现错误时返回的值,其中包括不支持的类型转换。参数可以是任何有效表达式。 如果未指定,此操作则会在出现错误时引发错误并停止。 | |||||||||||||||||||||||||||
onNull |
除 $convert
外,当默认 "onError" 和 "onNull" 行为可以接受时,MongoDB 还提供以下聚合操作符作为速记:
行为
转换为布尔值
下表列出了可转换为布尔值的输入类型:
输入类型 | 行为 |
---|---|
阵列 | 返回 true |
二进制数据 | 返回 true |
布尔 | 不操作。返回布尔值。 |
代码 | 返回 true |
Date | 返回 true |
Decimal 数据类型 | Returns true if not zero Return false if zero |
double | Returns true if not zero Return false if zero |
整型 | Returns true if not zero Return false if zero |
JavaScript | 返回 true |
Long | Returns true if not zero Return false if zero |
Max key | 返回 true |
最小键值 | 返回 true |
null | 返回为 |
对象 | 返回 true |
ObjectId | 返回 true |
正则表达式 | 返回 true |
字符串 | 返回 true |
时间戳 | 返回 true |
要详细了解 MongoDB 中的数据类型,请参阅 BSON 类型。
下表列出了一些转换为布尔值的示例:
例子 | 结果 | ||||
---|---|---|---|---|---|
| true | ||||
| false | ||||
| true | ||||
| true | ||||
| false | ||||
| true | ||||
| true | ||||
| true | ||||
| true | ||||
| true | ||||
| null |
转换为整数
下表列出了可转换为整数的输入类型:
输入类型 | 行为 |
---|---|
布尔 | Returns 0 for false .Returns 1 for true . |
double | 返回截断后的值。 截断后的 double 值必须介于整数的最小值与最大值之间。 如果 double 值的截断值小于最小整数值或大于最大整数值,则无法转换该 double 值。 |
Decimal 数据类型 | 返回截断后的值。 截断后的十进制值必须介于整数的最小值与最大值之间。 如果十进制数值的截断值小于最小整数值或大于最大整数值,则无法转换该十进制数值。 |
整型 | 不操作。返回整数值。 |
Long | 以整数形式返回该长整型值。 该长整型值必须介于整数的最小值与最大值范围之间。 不能转换小于最小整数值或大于最大整数值的长整数值。 |
字符串 | 以整数形式返回字符串的数值。 该字符串值必须是以 10 为基数的整数(例如 无法转换浮点数、十进制数或非十进制数的字符串值(例如 |
下表列出了转换为整数的部分示例:
例子 | 结果 | ||||
---|---|---|---|---|---|
| 1 | ||||
| 0 | ||||
| 1 | ||||
| 5 | ||||
| 错误 | ||||
| 5000 | ||||
| 错误 | ||||
| -2 | ||||
| 错误 | ||||
| null |
转换为小数
下表列出了可转换为十进制值的输入类型:
输入类型 | 行为 |
---|---|
布尔 | Returns Decimal128( "0" ) for false .Returns Decimal128( "1" ) for true . |
double | 以十进制形式返回 double 值。 |
Decimal 数据类型 | 不操作。返回该十进制数。 |
整型 | 以十进制形式返回该整型值。 |
Long | 以十进制形式返回该长值。 |
字符串 | 以十进制形式返回该字符串的数值。 字符串值必须是以 10 为基数的数值(例如 无法转换不以 10 为基数的字符串值(例如 |
Date | 返回日期值对应的纪元起的毫秒数。 |
下表列出了转换为十进制值的部分示例:
例子 | 结果 | ||||
---|---|---|---|---|---|
| Decimal128("1") | ||||
| Decimal128("0") | ||||
| Decimal128("2.50000000000000") | ||||
| Decimal128("5") | ||||
| Decimal128("10000") | ||||
| Decimal128("-5.5") | ||||
| Decimal128("1522039108044") |
转换为 double
下表列出了可转换为 double 的输入类型:
输入类型 | 行为 |
---|---|
布尔 | Returns NumberDouble(0) for false .Returns NumberDouble(1) for true . |
double | 不操作。返回 double。 |
Decimal 数据类型 | 以 double 形式返回该十进制值。 该十进制值必须介于 double 的最小值与最大值范围之间。 如果某一十进制值的值小于最小 double 值或大于最大 double 值,则无法转换该十进制值。 |
整型 | 以 double 形式返回该 int 值。 |
Long | 以 double 形式返回该 long 值。 |
字符串 | 以 double 形式返回该字符串的数值。 该字符串值必须是以 10 为基数的数值(例如 无法转换不以 10 为基数的字符串值(例如 |
Date | 返回日期值对应的纪元起的毫秒数。 |
下表列出了转换为 double 的部分示例:
例子 | 结果 | ||||
---|---|---|---|---|---|
| 1 | ||||
| 0 | ||||
| 2.5 | ||||
| 5 | ||||
| 10000 | ||||
| - 5.5 | ||||
| 50000000000 | ||||
| 1522039108044 |
转换为长整型值
下表列出了可转换为长整型的输入类型:
输入类型 | 行为 |
---|---|
布尔 | Returns 0 for false .Returns 1 for true . |
double | 返回截断后的值。 截断后的 double 值必须介于长整型值的最小值与最大值之间。 如果 double 值的截断值小于最小长值或大于最大长值,则无法转换该 double 值。 |
Decimal 数据类型 | 返回截断后的值。 截断后的十进制值必须介于长整型值的最小值与最大值之间。 如果某一十进制数值的截断值小于最小长整型值或大于最大长整型值,则无法转换该十进制数值。 |
整型 | 以 long 形式返回整数值。 |
Long | 不操作。返回长整型值。 |
字符串 | 返回字符串的数值。 该字符串值必须是以 10 为基数的长整型值(例如 无法转换浮点数、十进制数或非十进制数的字符串值(例如 |
Date | 将“日期”转换为自纪元起的毫秒数。 |
下表列出了转换为长整型值的部分示例:
例子 | 结果 | ||||
---|---|---|---|---|---|
| Long("1") | ||||
| Long("0") | ||||
| Long("2") | ||||
| Long("5") | ||||
| 错误 | ||||
| Long("8") | ||||
| Long("1522039108044") | ||||
| Long("2") | ||||
| 错误 | ||||
| null |
转换为日期
下表列出了可转换为日期的输入类型:
输入类型 | 行为 |
---|---|
double | 返回与截断后的由 double 值表示的毫秒数相对应的日期。 正数对应于 1970 年 1 月 1 日以来的毫秒数。 负数对应于 1970 年 1 月 1 日之前的毫秒数。 |
Decimal 数据类型 | 返回与由截断后的十进制值表示的毫秒数相对应的日期。 正数对应于 1970 年 1 月 1 日以来的毫秒数。 负数对应于 1970 年 1 月 1 日之前的毫秒数。 |
Long | 返回与该长值表示的毫秒数相对应的日期。 正数对应于 1970 年 1 月 1 日以来的毫秒数。 负数对应于 1970 年 1 月 1 日之前的毫秒数。 |
字符串 | 返回与日期字符串相对应的日期。 该字符串必须为有效的日期字符串,例如:
|
ObjectId | 返回与对象标识符的时间戳对应的日期。 |
时间戳 | 返回与时间戳相对应的日期。 |
下表列出了转换为日期的部分示例:
例子 | 结果 | ||||
---|---|---|---|---|---|
| ISODate("1973-10-20T21:20:00.000Z") | ||||
| ISODate("2009-09-19T14:53:56.000Z") | ||||
| ISODate("2004-11-09T11:33:20.000Z") | ||||
| ISODate("1935-02-22T12:26:40.000Z") | ||||
| ISODate("2018-03-27T04:08:58.000Z") | ||||
| ISODate("2018-03-03T00:00:00.000Z") | ||||
| ISODate("2018-03-20T06:00:06.000Z") | ||||
| 错误 | ||||
| ISODate("2021-11-23T17:21:58.000Z") |
转换为对象标识符
下表列出可以转换为对象标识符的输入类型:
输入类型 | 行为 |
---|---|
字符串 | 以长度为 24 的 16 进制字符串返回对象标识符。 不能转换不是长度 24 的十六进制字符串的字符串值。 |
下表列出了转换为日期的部分示例:
例子 | 结果 | ||||
---|---|---|---|---|---|
| ObjectId("5ab9cbfa31c2ab715d42129e") | ||||
| 错误 |
转换为字符串
下表列出了可转换为字符串的输入类型:
输入类型 | 行为 |
---|---|
布尔 | 以字符串形式返回该布尔值。 |
double | 以字符串形式返回该 double 值。 |
Decimal 数据类型 | 以字符串形式返回该十进制值。 |
整型 | 以字符串形式返回该整型值。 |
Long | 以字符串形式返回该长整型值。 |
ObjectId | 以十六进制字符串形式返回该 ObjectId 值。 |
字符串 | 不操作。返回该字符串值。 |
Date | 以字符串形式返回该日期。 |
下表列出了转换为字符串的部分示例:
例子 | 结果 | ||||
---|---|---|---|---|---|
| "true" | ||||
| "false" | ||||
| "2.5" | ||||
| "2" | ||||
| "1000" | ||||
| "5ab9c3da31c2ab715d421285" | ||||
| "2018-03-27T16:58:51.538Z" |
例子
使用以下文档创建集合 orders
:
db.orders.insertMany( [ { _id: 1, item: "apple", qty: 5, price: 10 }, { _id: 2, item: "pie", qty: 10, price: Decimal128("20.0") }, { _id: 3, item: "ice cream", qty: 2, price: "4.99" }, { _id: 4, item: "almonds" }, { _id: 5, item: "bananas", qty: 5000000000, price: Decimal128("1.25") } ] )
对 orders
集合执行的以下聚合操作会将 price
转换为十进制值:
// Define stage to add convertedPrice and convertedQty fields with // the converted price and qty values. // If price or qty values are missing, the conversion returns a // value of decimal value or int value of 0. // If price or qty values cannot be converted, the conversion returns // a string priceQtyConversionStage = { $addFields: { convertedPrice: { $convert: { input: "$price", to: "decimal", onError: "Error", onNull: Decimal128("0") } }, convertedQty: { $convert: { input: "$qty", to: "int", onError:{ $concat: [ "Could not convert ", { $toString:"$qty" }, " to type integer." ] }, onNull: Int32("0") } }, } }; totalPriceCalculationStage = { $project: { totalPrice: { $switch: { branches: [ { case: { $eq: [ { $type: "$convertedPrice" }, "string" ] }, then: "NaN" }, { case: { $eq: [ { $type: "$convertedQty" }, "string" ] }, then: "NaN" }, ], default: { $multiply: [ "$convertedPrice", "$convertedQty" ] } } } } }; db.orders.aggregate( [ priceQtyConversionStage, totalPriceCalculationStage ])
该操作将返回以下文档:
{ _id: 1, totalPrice: Decimal128("50") }, { _id: 2, totalPrice: Decimal128("200.0") }, { _id: 3, totalPrice: Decimal128("9.98") }, { _id: 4, totalPrice: Decimal128("0") }, { _id: 5, totalPrice: 'NaN' }