定义
行为
输入类型期望
下表描述了不同输入类型的 $toObject 行为:
输入类型 | 行为 |
|---|---|
字符串 | 返回与字符串中的内容相对应的文档。 |
空值或缺失 | 返回 null。 |
解析规则
将字符串转换为对象时,$toObject:
要求顶级值是一个对象。如果该字符串不表示对象,则
$toObject出错。不解释扩展JSON类型包装器,例如
$oid、$date或Timestamp(...)。这些在结果中仍然是字符串或嵌套对象。当对象包含重复的字段名称时,保留最后一个值。同一字段的早期值将被丢弃。
数值类型映射
$toObject 根据数值类型的值和格式进行转换:
32 位有符号范围内的整数变为
int。超出 32 位范围但在 64 位符号范围内的整数将变为
long。超出 64 位有符号范围的整数会变为
double,这可能会导致精度损失。带有点或指数表示法的数字变为
double。
示例
下表显示使用 $toObject 将字符串转换为对象的示例:
例子 | 结果 |
|---|---|
| { a: 1, b: 2 } |
| { } |
| 错误:输入与预期类型“对象”不匹配 |
| 错误:输入不代表有效的JSON:意外的独立运行值 |
| 错误:输入不代表有效的JSON:非法嵌入空字节 注意该字符串必须包含表示有效对象的字符。 |
| { name: 'fox00o' } |
| { a: 3, b: 2 } 注意保留同一字段的最后一个值。 |
| { foo: null } |
| { foo: false } |
| { ['__proto__']: { foo: null } } |
| { foo: 'NaN' } |
| { foo: 123 } |
| { foo: Long('4294967296') } 注意该数字超出了 32 位有符号范围,因此将其转换为长整型。 |
| { foo: 1.123123 } |
| { foo: 1200 } |
| { largePos: 18446744073709552000 } 注意该数字超出了 64 位有符号范围,因此会转换为具有精度损失的双精度值。 |
| { largeNeg: -18446744073709552000 } 注意该数字超出了 64 位有符号范围,因此会转换为具有精度损失的双精度值。 |
| null |
将字符串转换为对象
创建一个集合,其中的字符串存储在一个字段中:
db.jsonStrings.insertOne({ _id: 1, config: '{"feature": true, "threshold": 10}' })
以下聚合将 config 中的字符串转换为对象:
db.jsonStrings.aggregate([ { $project: { _id: 0, parsedConfig: { $toObject: "$config" } } } ])
此操作返回一个文档,其中 parsedConfig 是具有布尔值和整数值的嵌套文档:
{ parsedConfig: { feature: true, threshold: 10 } }
注意
如果转换操作遇到错误,聚合操作会停止并抛出错误。要覆盖此行为,请改为使用 $convert。