如何在Mongo Shell中获取MongoDB文档字段的BSON类型
MongoDB Shell 精准校验字段底层BSON类型的方法
原生typeof的局限性
Mongo Shell(mongosh)基于JavaScript运行时实现,所有BSON数值类型在解析为JS内存对象时,都会被统一转换为原生Number类型。因此使用JS原生typeof运算符检测时,无论底层存储是32位整数、双精度浮点还是64位长整数,结果都会返回number,完全丢失原始BSON层的类型区分信息。
可落地的精准校验方案
方法1:调用元素原生的getBSONType()方法
mongosh为所有从数据库解析出的BSON元素挂载了内置方法,可直接读取元素对应的原始BSON类型编码,不会经过JavaScript层的类型抹平。
使用示例:
// 获取ONE文档的第一个items元素 const firstItemOfOne = db.entities.findOne({_id: "ONE"}).items[0] // 输出元素对应的BSON类型编码 firstItemOfOne.getBSONType()
返回编码和实际类型的对应关系:
- 返回
1:双精度浮点类型 - 返回
16:32位整数类型 - 返回
18:64位长整数类型
结合场景的实际验证效果: - 执行上述代码读取
ONE.items[0],会返回16,符合32位整数的编码特征 - 读取
TWO.items[0]执行相同方法,会返回1,符合双精度浮点的编码特征
方法2:通过$type查询操作反向匹配
可以直接通过查询语句匹配指定BSON类型的字段,语句能返回目标文档,就说明字段的底层存储类型和指定的$type值完全一致。
使用示例:
// 匹配items第0位为32位整数的文档 db.entities.find({ _id: "ONE", "items.0": {$type: "int"} })
如果查询返回ONE文档,说明该位置存储的是32位整数;如果将$type值替换为"double"无法匹配到文档,就可以反向确认两者的BSON类型差异。
提示:
$type是直接匹配BSON解析层的原始类型,不受JS层类型转换的影响,校验结果准确。
老旧版本Shell的兼容方案
如果使用的是没有内置mongosh能力的老旧版本独立Mongo Shell,可通过判断元素是否为NumberInt、NumberLong的实例区分数值类型:双精度浮点数会被解析为原生JS Number实例,32位整数、64位长整数会被封装为对应的特殊包装对象。
内容的提问来源于stack exchange,提问作者fgalan
相关产品推荐
相关产品推荐

