“文档” 菜单
文档首页
/
MongoDB Manual
/

BSON类型

在此页面上

  • 二进制数据
  • ObjectId
  • 字符串
  • 时间戳
  • Date

BSON 是一种二进制序列化格式,用在 MongoDB 中存储文档和进行远程过程调用。BSON 规范位于 bsonspec.org

每个 BSON 类型都同时具有整数和字符串标识符,如下表所列:

类型
数值
别名
注意
双精度
1
"double"
字符串
2
"string"
对象
3
"object"
阵列
4
"array"
二进制数据
5
"binData"
未定义
6
"undefined"
已弃用。
ObjectId
7
"objectId"
布尔
8
"bool"
Date
9
"date"
null
10
"null"
正则表达式
11
"regex"
数据库指针
12
"dbPointer"
已弃用。
JavaScript
13
"javascript"
符号
14
"symbol"
已弃用。
32 位整数
16
"int"
时间戳
17
"timestamp"
64 位整型
18
"long"
Decimal128
19
"decimal"
最小键
-1
"minKey"
Max key
127
"maxKey"

要确定某一字段的类型,请参阅类型检查。

如果将 BSON 转换为 JSON,请参阅扩展 JSON 参考资料。

以下部分介绍了特定 BSON 类型的特别注意事项。

BSON 二进制binData值是字节数组。binData 值有一个子类型,表示如何解释二进制数据。下表显示了子类型。

数值
子类型
0
通用二进制子类型
1
函数数据
2
二进制(旧版)
3
UUID(旧)
4
UUID
5
MD5
6
加密的 BSON 值
7

压缩时间序列数据

5.2 版本中的新增功能

128
自定义数据

ObjectId(对象标识符)很小,可能是唯一的,生成速度快并且是有序的。ObjectId 值的长度为 12 个字节,包含:

  • 一个 4 字节时间戳,它表示 ObjectId 的创建时间,并以自 UNIX 纪元以来的秒数为单位进行测量。

  • 每个进程会生成一次 5 字节随机值。这个随机值对于机器和进程是唯一的。

  • 三字节递增计数器(初始化为随机值)。

对于时间戳和计数器值,最高有效字节在字节序列中最先出现(大端字节序)。对于其他 BSON 值,最低有效字节最先出现(小端字节序)。

如果使用整数值创建对象标识符(ObjectId),则该整数将替换时间戳。

在 MongoDB 中,存储在集合中的每个文档都需要一个唯一的 _id 字段作为主键。如果插入的文档省略了 _id 字段,则 MongoDB 驱动程序会自动为 _id 字段生成一个 ObjectId

这也适用于通过执行 upsert: true 的更新操作插入的文档。

MongoDB 客户端应添加一个具有唯一 ObjectId 的 _id 字段。为 _id 字段使用 ObjectId 还能带来以下好处:

  • mongosh 中,可以使用 ObjectId.getTimestamp() 方法访问 ObjectId 的创建时间。

  • 对存储 ObjectId 值的 _id 字段进行排序,大致相当于按创建时间排序。

    重要

    虽然 ObjectId 值会随着时间的推移而增加,但它们不一定是单调的。这是因为它们:

    • 仅有一秒的时间分辨率,因此在同一秒内创建的 ObjectId 值不能保证顺序,并且

    • 由可能具有不同系统时钟的客户端生成。

使用 ObjectId() 方法可设置和检索 ObjectId 值。

从 MongoDB 5.0 开始,mongosh 将取代旧版的 mongo shell。ObjectId() 方法在 mongosh 中的运行方式与在旧版的 mongo shell 中的运行方式不同。有关旧版方法的更多信息,请参阅旧版的 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 位是递增的 ordinal

虽然 BSON 格式是小端字节序,因此首先存储最低有效位,但在所有平台上,mongod 实例始终先比较 time_t 值,然后再比较 ordinal 值,不受字节序的影响。

在单个 mongod 实例中,时间戳值总是唯一的。

在复制中,oplog 有一个 ts 字段。该字段的值反映利用 BSON 时间戳值确定的操作时间。

注意

这种 BSON 时间戳类型供 MongoDB 内部使用。对于多数情况,应用程序开发中需要使用 BSON 日期类型。请参阅日期,获取更多信息。

当插入的文档包含具有空时间戳值的顶级字段时,MongoDB 会将空时间戳值替换为当前时间戳值,但以下情况除外。_id 字段如果本身包含空时间戳值,则将始终按原样插入而不被替换。

例子

插入附带空时间戳值的文档:

db.test.insertOne( { ts: new Timestamp() } );

随后运行 db.test.find() 将返回一个类似如下内容的文档:

{ "_id" : ObjectId("542c2b97bac0595474108b48"), "ts" : Timestamp(1412180887, 1) }

服务器已将 ts 的空时间戳值替换为插入时的时间戳值。

“BSON Date”(BSON 日期)是一个 64 位整数,它表示自 UNIX 纪元(1970 年 1 月 1 日)以来的毫秒数。因此,过去与未来的可表示日期范围便可达到约 2.9 亿年。

官方 BSON 规范将 BSON 日期类型称为 UTC 日期时间

BSON Date 类型为有符号值。[2] 负值代表 1970 年之前的日期。

例子

使用 mongosh 中的 new Date() 构造函数来构造日期:

var mydate1 = new Date()

例子

使用 mongosh 中的 ISODate() 构造函数来构造日期:

var mydate2 = ISODate()

例子

以字符串形式返回该日期值:

mydate1.toString()

例子

返回 Date 值的月份部分;月份从零开始索引,因此一月是月份 0

mydate1.getMonth()
[2] 在 2.0 版本之前,Date 值被错误解释为无符号整数,从而会影响针对 Date 字段的排序、范围查询和索引。由于升级时不会重新创建索引,因此使用早期版本对 Date 值创建索引时请重新创建索引,且 1970 年之前的日期对您的应用程序来说均为相对日期。
← MongoDB