Docs 菜单
Docs 主页
/
数据库手册
/ / /

$convert(表达式操作符)

$convert

将数值转换为指定类型。

可以使用 $convert 查找托管在以下环境中的部署:

  • MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务

  • MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本

  • MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本

在版本8.0中进行了更改

{
$convert:
{
input: <expression>,
to: <type expression> || {
type: <type expression>,
subtype: <int>
},
format: <string>,
onError: <expression>,
onNull: <expression>
}
}

$convert 接受包含以下字段的文档:

字段
必要性
说明

input

必需

参数可以是任何有效的表达式。有关表达式的更多信息,请参阅表达式

从MongoDB 8.1 开始,如果将 to设立为以下值之一,则可以将 input设立为 binData

  • int

  • long

  • double

将值转换为 binData 时, MongoDB还支持这些数字类型作为输入。

to

必需

指定将 input 表达式转换为的类型。您可以将 to 设置为以下值之一:

  • 目标类型的字符串或数字标识符。请参阅 to.type

  • 包含字段 to.typeto.subtype 的对象。使用此格式转换为 binData 并指定 binData 子类型。

to.type

如果将 to 指定为对象,则为必填项

to.subtype

Optional

如果 to.typebinData,则 to.subtype 会指定要转换到的 binData 子类型。您可以为 to.subtype 指定以下值之一:

数值
说明

0

通用二进制子类型

1

函数数据

2

二进制(旧版)

3

UUID(旧)

4

UUID

5

MD5

6

加密的 BSON 值

7

压缩时间序列数据

5.2 版本中的新增功能

8

敏感数据,例如密钥或密码。 MongoDB 不会记录子类型为 8 的二进制数据的字面值。相反,MongoDB 会记录占位符值###

9

向量数据是由相同类型的数字组成的密集数组。

128

自定义数据

默认值: 0(通用二进制子类型)

byteOrder

Optional

binData 和数字类型之间的转换指定大端字节序或小端字节序。如果未指定,默认为小端字节顺序。

format

binData 和字符串相互转换时必需

指定 binData 和字符串之间的转换格式

  • base64

  • base64url

  • utf8

  • hex

  • uuid

如果 formatuuidto.subtype 必须是 4

onError

Optional

转换期间出现错误时返回的值,其中包括不支持的类型转换。参数可以是任何有效表达式

如果未指定,此操作则会在出现错误时引发错误并停止。

onNull

Optional

input 为 null 或缺失时要返回的值。参数可以是任何有效的表达式

$convert如果未指定,则当input 为 null 或缺失时, 会返回 null。

$convert 外,当默认 "onError" 和 "onNull" 行为可以接受时,MongoDB 还提供以下聚合操作符作为速记:

从MongoDB 8.1 开始,如果将 to设立为以下值之一,则可以将 input设立为 binData

  • int

  • long

  • double

从MongoDB 8.1 开始,尝试在不同 binData 子类型之间进行转换时,$convert 会返回错误。在MongoDB 8.0 中,$convert 返回原始值和原始子类型:不执行转换。8.0 之前的MongoDB版本没有 binData 转换。

将数字类型转换为 binData 时:

  • int 成为 4 字节的 binData

  • long 成为 8 字节的 binData

  • double 成为 8 字节的 binData

数值输出的 byteOrder 默认为“little”,即最低有效字节在前。相反,“big”会将最高有效字节放在第一位。

long 转换为 binData

db.t.insertOne({a: Long(42)})
db.t.aggregate([
{
$project: {
convertedBD: {
$convert: {
input: Long(42),
to: "binData",
}
},
}
}
])
{
_id: ObjectId('67dda0195a99e592590143e8'),
convertedBD: Binary.createFromBase64('KgAAAAAAAAA=', 0)
}

使用大端字节序将 long 转换为 binData

db.t.insertOne({a: Long(42)})
db.t.aggregate([
{
$project: {
convertedBD: {
$convert: {
input: Long(42),
to: "binData",
byteOrder: "big",
}
},
}
}
])
{
_id: ObjectId('67ddb27c5a99e592590143ec'),
convertedBD: Binary.createFromBase64('AAAAAAAAACo=', 0),
}

double 转换为 binData

db.t.insertOne({a: Double(42.0)})
db.t.aggregate([
{
$project: {
convertedBD: {
$convert: {
input: Double(42),
to: "binData",
}
},
}
}
])
{
_id: ObjectId('67ddb3cf5a99e592590143ee'),
convertedBD: Binary.createFromBase64('AAAAAAAARUA=', 0)
}

int 转换为 binData

db.t.insertOne({a: 42})
db.t.aggregate([
{
$project: {
convertedBD: {
$convert: {
input: 42,
to: "binData",
}
},
}
}
])
{
_id: ObjectId('67ddb43a5a99e592590143ef'),
convertedBD: Binary.createFromBase64('KgAAAA==', 0)
}

MongoDB还支持 binData 和字符串之间的转换。

以下示例演示如何将字符串转换为 binData。

例子
结果
{
input: "hn3uUsMxSE6S0cVkebjmfg==",
to: {
type: "binData",
subtype: 0
},
format: "base64"
}
Binary.createFromBase64('hn3uUsMxSE6S0cVkebjmfg==', 0)
{
input: "hn3uUsMxSE6S0cVkebjmfg==",
to: "binData",
format: "base64"
}
Binary.createFromBase64('hn3uUsMxSE6S0cVkebjmfg==', 0)
{
input: "867dee52-c331-484e-92d1-c56479b8e67e",
to: {
type: "binData",
subtype: 0
},
format: "base64"
}
Failed to parse BinData '867dee52-c331-484e-92d1-c56479b8e67e'
in $convert with no onError value: Input is not a valid base64
string.
{
input: "hn3uUsMxSE6S0cVkebjmfg==",
to: {
type: "binData",
subtype: 4
},
format: "base64"
}
Failed to parse BinData 'hn3uUsMxSE6S0cVkebjmfg==' in $convert
with no onError value: Input is not a valid base64 string.
{
input: "867dee52-c331-484e-92d1-c56479b8e67e",
to: {
type: "binData",
subtype: 4
},
format: "uuid"
}
UUID('867dee52-c331-484e-92d1-c56479b8e67e')
{
input: "äöäöä",
to: {
type: "binData",
subtype: 4
},
format: "uuid"
}
Failed to parse BinData 'äöäöä' in $convert with no onError
value: Input is not a valid UUID string.
{
input: "867dee52-c331-484e-92d1-c56479b8e67e",
to: { type: "binData" },
format: "uuid"
}
Failed to parse BinData '867dee52-c331-484e-92d1-c56479b8e67e'
in $convert with no onError value: Only the UUID subtype (4)
is allowed with the 'uuid' format.

注意

从MongoDB 8.1 开始,尝试在不同 binData 子类型之间进行转换时,$convert 会返回错误。在MongoDB 8.0 中,$convert 返回原始值和原始子类型:不执行转换。8.0 之前的MongoDB版本没有 binData 转换。

下表列出了可转换为布尔值的输入类型:

输入类型
行为

阵列

返回 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

返回为 onNull 选项指定的值。默认情况下,返回 null。

对象

返回 true

ObjectId

返回 true

正则表达式

返回 true

字符串

返回 true

时间戳

返回 true

要详细了解 MongoDB 中的数据类型,请参阅 BSON 类型

下表列出了一些转换为布尔值的示例:

例子
结果
{ input: true, to: "bool" }

true

{ input: false, to: "bool" }

false

{ input: 1.99999, to: "bool" }

true

{ input: Decimal128( "5" ), to: "bool" }

true

{ input: Decimal128( "0" ), to: "bool" }

false

{ input: 100, to: "bool" }

true

{
input: ISODate( "2018-03-26T04:38:28.044Z" ),
to: "bool"
}

true

{ input: "hello", to: "bool" }

true

{ input: "false", to: "bool" }

true

{ input: "", to: "bool" }

true

{ input: null, to: "bool" }

null

提示

下表列出了可转换为整数的输入类型:

输入类型
行为

布尔

Returns 0 for false.
Returns 1 for true.

BinData

以整数形式返回 binData 值。binData 被解释为二进制的有符号补码有符号整数。

binData 值中的字节数必须为 124

如果 input 的长度超出预期,则会产生错误。您可以通过配置 $convert.onError 来控制此行为。

double

返回截断后的值。

截断后的 double 值必须介于整数的最小值与最大值之间。

如果 double 值的截断值小于最小整数值或大于最大整数值,则无法转换该 double 值。

Decimal 数据类型

返回截断后的值。

截断后的十进制值必须介于整数的最小值与最大值之间。

如果十进制数值的截断值小于最小整数值或大于最大整数值,则无法转换该十进制数值。

整型

不操作。返回整数值。

Long

以整数形式返回该长整型值。

该长整型值必须介于整数的最小值与最大值范围之间。

不能转换小于最小整数值或大于最大整数值的长整数值。

字符串

以整数形式返回字符串的数值。

该字符串值必须是以 10 为基数的整数(例如 "-5""123456"),且介于整数的最小值与最大值范围之间。

无法转换浮点数、十进制数或非进制数的字符串值(例如 "-5.0""0x6400")或超出整数最小值和最大值的值。

下表列出了转换为整数的部分示例:

例子
结果
{ input: true, to: "int" }

1

{ input: false, to: "int" }

0

{ input: 1.99999, to: "int" }

1

{ input: Decimal128( "5.5000" ), to: "int" }

5

{
input: Decimal128( "9223372036000.000" ),
to: "int"
}

错误

{ input: Long( "5000" ), to: "int" }

5000

{ input: Long( "922337203600" ), to: "int" }

错误

{ input: "-2", to: "int" }

-2

{ input: "2.5", to: "int" }

错误

{ input: null, to: "int" }

null

{
input: Binary(Buffer.from("00100000", "hex"), 0),
to: "int",
byteOrder: "big",
}

1048576

{
input: Binary(Buffer.from("FFFFE796", "hex"), 0),
to: "int",
}

-1763180545

{
input: Binary(Buffer.from("001000000000000", "hex"), 0),
to: "int",
byteOrder: "big",
}

错误:由于长度 7 无效,无法转换 BinData

提示

$toInt 操作符。

下表列出了可转换为十进制值的输入类型:

输入类型
行为

布尔

Returns Decimal128( "0" ) for false.
Returns Decimal128( "1" ) for true.

double

以十进制形式返回 double 值。

Decimal 数据类型

不操作。返回该十进制数。

整型

以十进制形式返回该整型值。

Long

以十进制形式返回该长值。

字符串

以十进制形式返回该字符串的数值。

字符串值必须是以 10 为基数的数值(例如"-5.5""123456")。

无法转换不以 10 为基数的字符串值(例如 "0x6400"

Date

返回日期值对应的纪元起的毫秒数。

下表列出了转换为十进制值的部分示例:

例子
结果
{ input: true, to: "decimal" }

Decimal128("1")

{ input: false, to: "decimal" }

Decimal128("0")

{ input: 2.5, to: "decimal" }

Decimal128("2.50000000000000")

{ input: Int32( 5 ), to: "decimal" }

Decimal128("5")

{ input: Long( 10000 ), to: "decimal" }

Decimal128("10000")

{ input: "-5.5", to: "decimal" }

Decimal128("-5.5")

{
input: ISODate( "2018-03-26T04:38:28.044Z" ),
to: "decimal"
}

Decimal128("1522039108044")

下表列出了可转换为 double 的输入类型:

输入类型
行为

布尔

Returns NumberDouble(0) for false.
Returns NumberDouble(1) for true.

BinData

以双精度值形式返回 binData 值。 binData 被解释为 IEEE 754 单精度或双精度点。

binData 值中的字节数必须为 48

如果 input 的长度超出预期,则会产生错误。您可以通过配置 $convert.onError 来控制此行为。

double

不操作。返回 double。

Decimal 数据类型

以 double 形式返回该十进制值。

该十进制值必须介于 double 的最小值与最大值范围之间。

如果某一十进制值的值小于最小 double 值或大于最大 double 值,则无法转换该十进制值。

整型

以 double 形式返回该 int 值。

Long

以 double 形式返回该 long 值。

字符串

以 double 形式返回该字符串的数值。

该字符串值必须是以 10 为基数的数值(例如 "-5.5""123456"),且介于 double 值的最小值与最大值之间。

无法转换不以 10 为基数的字符串值(例如"0x6400")或超出 double 值最小值和最大值的值。

Date

返回日期值对应的纪元起的毫秒数。

下表列出了转换为 double 的部分示例:

例子
结果
{ input: true, to: "double" }

1

{ input: false, to: "double" }

0

{ input: 2.5, to: "double" }

2.5

{ input: Int32( 5 ), to: "double" }

5

{ input: Long( "10000" ), to: "double" }

10000

{ input: "-5.5", to: "double" }

- 5.5

{ input: "5e10", to: "double" }

50000000000

{
input: ISODate( "2018-03-26T04:38:28.044Z" ),
to: "double"
}

1522039108044

{
input: Binary(Buffer.from("04CCCCCD", "hex"), 0),
to: "double",
byteOrder: "big",
}

4.814824932714571e-36

{
input: Binary(Buffer.from("0000", "hex"), 0),
to: "double",
byteOrder: "big",
}

错误:由于长度 2 无效,无法转换 binData

提示

下表列出了可转换为长整型的输入类型:

输入类型
行为

布尔

Returns 0 for false.
Returns 1 for true.

BinData

以长整型形式返回 binData 值。binData 被解释为二进制的有符号补码有符号整数。

binData 值中的字节数必须为 1248

如果 input 的长度超出预期,则会产生错误。您可以通过配置 $convert.onError 来控制此行为。

double

返回截断后的值。

截断后的 double 值必须介于长整型值的最小值与最大值之间。

如果 double 值的截断值小于最小长值或大于最大长值,则无法转换该 double 值。

Decimal 数据类型

返回截断后的值。

截断后的十进制值必须介于长整型值的最小值与最大值之间。

如果某一十进制数值的截断值小于最小长整型值或大于最大长整型值,则无法转换该十进制数值。

整型

以 long 形式返回整数值。

Long

不操作。返回长整型值。

字符串

返回字符串的数值。

该字符串值必须是以 10 为基数的长整型值(例如 "-5""123456"),且介于长整型值的最小值与最大值之间。

无法转换浮点数、十进制数或非进制数的字符串值(例如 "-5.0""0x6400")或是超出长整型值的最小值与最大值的值。

Date

将“日期”转换为自纪元起的毫秒数。

下表列出了转换为长整型值的部分示例:

例子
结果
{ input: true, to: "long" }

Long("1")

{ input: false, to: "long" }

Long("0")

{ input: 2.5, to: "long" }

Long("2")

{ input: Decimal128( "5.5000" ), to: "long" }

Long("5")

{
input: Decimal128( "9223372036854775808.0" ),
to: "long"
}

错误

{ input: Int32( 8 ), to: "long" }

Long("8")

{
input: ISODate( "2018-03-26T04:38:28.044Z" ),
to: "long"
}

Long("1522039108044")

{ input: "-2", to: "long" }

Long("2")

{ input: "2.5", to: "long" }

错误

{ input: null, to: "long" }

null

{
input: Binary(Buffer.from("001000000", "hex"), 0),
to: "long",
byteOrder: "big",
}

Long("1048576")

提示

下表列出了可转换为日期的输入类型:

输入类型
行为

double

返回与截断后的由 double 值表示的毫秒数相对应的日期。

正数对应于 1970 年 1 月 1 日以来的毫秒数。

负数对应于 1970 年 1 月 1 日之前的毫秒数。

Decimal 数据类型

返回与由截断后的十进制值表示的毫秒数相对应的日期。

正数对应于 1970 年 1 月 1 日以来的毫秒数。

负数对应于 1970 年 1 月 1 日之前的毫秒数。

Long

返回与该长值表示的毫秒数相对应的日期。

正数对应于 1970 年 1 月 1 日以来的毫秒数。

负数对应于 1970 年 1 月 1 日之前的毫秒数。

字符串

返回与日期字符串相对应的日期。

该字符串必须为有效的日期字符串,例如:

  • "2018-03-03"

  • "2018-03-03T12:00:00Z"

  • "2018-03-03T12:00:00+0500"

ObjectId

返回与对象标识符的时间戳对应的日期。

时间戳

返回与时间戳相对应的日期。

下表列出了转换为日期的部分示例:

例子
结果
{
input: 120000000000.5,
to: "date"
}

ISODate("1973-10-20T21:20:00.000Z")

{
input: Decimal128( "1253372036000.50" ),
to: "date"
}

ISODate("2009-09-19T14:53:56.000Z")

{
input: Long( "1100000000000" ),
to: "date
}

ISODate("2004-11-09T11:33:20.000Z")

{
input: Long( "-1100000000000" ),
to: "date"
}

ISODate("1935-02-22T12:26:40.000Z")

{
input: ObjectId( "5ab9c3da31c2ab715d421285" ),
to: "date"
}

ISODate("2018-03-27T04:08:58.000Z")

{ input: "2018-03-03", to: "date" }

ISODate("2018-03-03T00:00:00.000Z")

{
input: "2018-03-20 11:00:06 +0500",
to: "date"
}

ISODate("2018-03-20T06:00:06.000Z")

{ input: "Friday", to: "date" }

错误

{
input: Timestamp( { t: 1637688118, i: 1 } ),
to: "date"
}

ISODate("2021-11-23T17:21:58.000Z")

提示

下表列出可以转换为对象标识符的输入类型:

输入类型
行为

字符串

以长度为 24 的 16 进制字符串返回对象标识符。

不能转换不是长度 24 的十六进制字符串的字符串值。

下表列出了转换为日期的部分示例:

例子
结果
{
input: "5ab9cbfa31c2ab715d42129e",
to: "objectId"
}

ObjectId("5ab9cbfa31c2ab715d42129e")

{
input: "5ab9cbfa31c2ab715d42129",
to: "objectId"
}

错误

提示

$toObjectId 操作符。

下表列出了可转换为字符串的输入类型:

输入类型
行为

BinData

以字符串形式返回二进制数据值。

布尔

以字符串形式返回该布尔值。

double

以字符串形式返回该 double 值。

Decimal 数据类型

以字符串形式返回该十进制值。

整型

以字符串形式返回该整型值。

Long

以字符串形式返回该长整型值。

ObjectId

以十六进制字符串形式返回该 ObjectId 值。

字符串

不操作。返回该字符串值。

Date

以字符串形式返回该日期。

下表列出了转换为字符串的部分示例:

例子
结果
{ input: true, to: "string" }

"true"

{ input: false, to: "string" }

"false"

{ input: 2.5, to: "string" }

"2.5"

{ input: Int32( 2 ), to: "string" }

"2"

{ input: Long( 1000 ), to: "string" }

"1000"

{
input: ObjectId( "5ab9c3da31c2ab715d421285" ),
to: "string"
}

"5ab9c3da31c2ab715d421285"

{
input: ISODate( "2018-03-27T16:58:51.538Z" ),
to: "string"
}

"2018-03-27T16:58:51.538Z"

{
input: BinData(4, "hn3f"),
to: "string",
format: "base64"
}

'hn3f'

提示

使用以下文档创建集合 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' }

注意

这些示例使用 mongosh。旧版 mongo Shell 中的默认类型有所不同。

后退

$cond

在此页面上