BSON 类型
BSON 是 MongoDB 中用于存储文档和执行远程过程调用的二进制序列化格式。BSON 规范位于bsonspec.org.
以下表格列出了每个 BSON 类型的整数和字符串标识符
类型 | 数字 | 别名 | 说明 |
---|---|---|---|
双精度浮点数 | 1 | "double" | |
字符串 | 2 | "string" | |
对象 | 3 | "object" | |
数组 | 4 | "array" | |
二进制数据 | 5 | "binData" | |
未定义 | 6 | "undefined" | 已弃用。 |
ObjectId | 7 | "objectId" | |
布尔值 | 8 | "bool" | |
日期 | 9 | "date" | |
空值 | 10 | "null" | |
正则表达式 | 11 | "regex" | |
数据库指针 | 12 | "dbPointer" | 已弃用。 |
JavaScript | 13 | "javascript" | |
符号 | 14 | "symbol" | 已弃用。 |
32 位整数 | 16 | "int" | |
时间戳 | 17 | "timestamp" | |
64位整数 | 18 | "long" | |
Decimal128 | 19 | "decimal" | |
最小键 | -1 | "minKey" | |
最大键 | 127 | "maxKey" |
$type
运算符支持使用这些值通过其BSON类型查询字段。$type
运算符还支持number
别名,它与整数、十进制、双精度和长BSON类型相匹配。$type
聚合运算符返回其参数的BSON类型。$isNumber
聚合运算符如果其参数是BSON整数、十进制、双精度或长,则返回true
。
要确定字段的类型,请参阅类型检查。
如果您将BSON转换为JSON,请参阅扩展JSON参考。
以下部分描述了特定BSON类型的特殊考虑事项。
二进制数据
BSON二进制binData
值是一个字节数组。binData
值有一个子类型,指示如何解释二进制数据。以下表显示了子类型
数字 | 描述 |
---|---|
0 | 通用二进制子类型 |
1 | 函数数据 |
2 | 二进制(旧版) |
3 | UUID(旧版) |
4 | UUID |
5 | MD5 |
6 | 加密BSON值 |
7 | 压缩时间序列数据 新版本5.2. |
8 | 敏感数据,例如键或机密。MongoDB不会记录具有子类型8的二进制数据的字面值。相反,MongoDB记录一个占位符值 ### 。 |
9 | 向量数据,这是密集填充的相同类型数字的数组。 |
128 | 自定义数据 |
ObjectId
ObjectId 是小型的、很可能是唯一的、快速生成的、有序的。ObjectId 的值长度为 12 字节,由以下部分组成:
一个 4 字节的时间戳,表示 ObjectId 的创建时间,以自 Unix 纪元以来的秒数衡量。
一个 5 字节的随机值,在每个进程生成一次。这个随机值对机器和进程是唯一的。
一个 3 字节的递增计数器,初始化为随机值。
对于时间戳和计数器值,字节序列中最显著的字节首先出现(大端)。这与其他 BSON 值不同,其他 BSON 值的最不显著字节首先出现(小端)。
如果使用整数值创建 ObjectId,则整数替换时间戳。
在 MongoDB 中,每个存储在集合中的文档都需要一个唯一标识的 _id 字段,该字段充当 主键。如果插入的文档省略了 _id
字段,MongoDB 驱动程序会自动为 _id
字段生成一个 ObjectId。
这同样适用于使用 upsert: true 的更新操作插入的文档。
MongoDB 客户端应添加一个具有唯一 ObjectId 的 _id
字段。使用 ObjectId 作为 _id
字段提供了以下额外好处
您可以使用
mongosh
中的ObjectId.getTimestamp()
方法访问ObjectId
创建时间。ObjectId 按创建时间大致排序,但不是完全排序的。在包含
ObjectId
值的_id
字段上对集合进行排序大致等同于按创建时间排序。
使用 ObjectId()
方法来设置和检索 ObjectId 值。
从 MongoDB 5.0 开始,mongosh
替代了旧的 mongo
shell。在 mongosh
中,ObjectId()
方法的工作方式与在旧的 mongo
shell 中不同。有关旧方法的信息,请参阅 Legacy mongo Shell。
字符串
BSON 字符串是 UTF-8 格式。通常,每种编程语言的驱动程序在序列化和反序列化 BSON 时,会将语言字符串格式转换为 UTF-8。这使得在 BSON 字符串中轻松存储大多数国际字符成为可能。[1] 此外,MongoDB $regex
查询支持 UTF-8 的正则表达式字符串。
[1] | 对于使用 UTF-8 字符集的字符串,对字符串使用 sort() 将是合理的。然而,由于内部 sort() 使用 C++ 的 strcmp api,排序顺序可能处理某些字符不正确。 |
时间戳
BSON 为 内部 MongoDB 使用具有特殊的时间戳类型,并且与常规的 Date 类型无关。此内部时间戳类型是一个 64 位值,其中
最高 32 位是一个
time_t
值(自 Unix 纪元以来的秒数)最低的32位是一个递增的
序数
,用于给定秒内的操作。
尽管BSON格式是低位优先,因此首先存储最低位,但无论平台如何,mongod
实例始终比较 time_t
值和 序数
值。
在复制中,oplog 有一个 ts
字段。该字段的值反映了操作时间,使用BSON时间戳值。
在单个 mongod
实例中,oplog 中的时间戳值始终是唯一的。
注意
BSON时间戳类型是用于 内部 MongoDB 的。对于大多数情况,在应用程序开发中,您将想要使用BSON日期类型。有关更多信息,请参阅日期。
日期
BSON日期是一个64位整数,表示自Unix纪元(1970年1月1日)以来的毫秒数。这导致可以表示的日期范围大约为290亿年前和未来。
官方BSON规范 将BSON日期类型称为 UTC日期时间。
BSON日期类型是有符号的。 [2] 负值表示1970年之前的日期。
示例
使用 mongosh
: 的 new Date()
构造函数创建日期。
var mydate1 = new Date()
示例
使用 mongosh
: 的 ISODate()
构造函数创建日期。
var mydate2 = ISODate()
示例
将日期值作为字符串返回
mydate1.toString()
示例
返回日期值的月份部分;月份是从零开始计数的,因此一月是月份 0
mydate1.getMonth()
[2] | 在版本2.0之前,Date 值被错误地解释为 无符号 整数,这影响了排序、范围查询以及 Date 字段的索引。由于在升级时索引不会重新创建,请重新索引,如果您使用早期版本在 Date 值上创建了索引,并且1970年之前的日期与您的应用程序相关。 |