目录
BSON是一种二进制序列化格式,用于在MongoDB中存储文档和进行远程过程调用。 有关BSON规范请访问bsonspec.org。
每种BSON类型标识符都具有整数和字符串两种表示方式,如下表:
类型 | 编号 | 别名 | 注释 |
Double | 1 | “double” |
|
String | 2 | “string” |
|
Object | 3 | “object” |
|
Array | 4 | “array” |
|
Binary Data | 5 | “binData” |
|
Undefined | 6 | “undefined” | Deprecated(已废弃) |
objectId | 7 | “objectId” |
|
Boolean | 8 | “bool” |
|
Date | 9 | “date” |
|
Null | 10 | “null” |
|
Regular Expression | 11 | “regex” |
|
DBPointer | 12 | “dbPointer” | Deprecated(已废弃) |
JavaScript | 13 | “javascript” |
|
Symbol | 14 | “symbol” | Deprecated(已废弃) |
JavaScript code with scope | 15 | “javascriptWithScope” | Deprecated in MongoDB 4.4 |
32-bit integer | 16 | “int” |
|
Timestamp | 17 | “timestamp” |
|
64-bit integer | 18 | “long” |
|
Decimal128 | 19 | “decimal” | New in version 3.4 |
Min Key | -1 | “minKey” |
|
Max Key | 127 | “maxKey” |
|
注:$ type用于筛选字段值是指定的BSON type(s)类型的文档。例如:
{ field: { $type: <BSON type> } }
{ field: { $type: [ <BSON type1> , <BSON type2>, ... ] } }
要查看字段类型,请参阅mongo Shell检查字段类型。
将BSON转换为JSON,请参阅MongoDB扩展的JSON。
以下各节描述了BSON类型需要特别注意的事项。
ObjectId比较小,还是唯一的,可以快速生成并排序。ObjectId值的长度为12个字节,包括:
虽然BSON格式本身是低位字节序,但时间戳和计数器值却是高位字节序,最有效字节出现在字节序列前端。
字节序,顾名思义字节的顺序,就是大于一个字节类型的数据在内存中的存放顺序(一个字节的数据当然就无需谈顺序的问题了)。
字节序分为两类:Big-Endian和Little-Endian,定义如下:
a) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
c) 网络字节序:TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序。
在MongoDB中,存储在集合中的每个文档都需要一个唯一的_id字段作为主键。如果插入的文档省略_id字段,则MongoDB驱动程序会自动为_id字段生成ObjectId类型值。
同理,通过upsert:true更新操作插入的文档时,若_id字段省略,也自动生成。
MongoDB客户端应添加一个唯一ObjectId值的_id字段。在_id字段中使用ObjectIds具有以下额外优点:
重要提示
尽管ObjectId值应随时间增加,但不一定是单调的。这是因为他们:
- ObjectId仅包含秒级时间戳,因此在同一秒内创建的ObjectId值没有保证的顺序
- 由客户端生成,客户端可能具有不同的系统时钟。
参考资料:ObjectId()
BSON字符串是UTF-8编码。
通常,在对BSON进行序列化和反序列化时,每种编程语言的驱动程序都会从该语言的字符串格式转换为UTF-8。这样就可以轻松地将大多数国际字符存储在BSON字符串中。 [1]此外,MongoDB $ regex查询在regex字符串中支持UTF-8。
[1]对于一个UTF-8字符集的字符串,对字符串使用sort()是合理的。但是,由于内部sort()使用C ++ strcmp api,因此排序顺序可能会错误地处理某些字符。
BSON有一种在MongoDB使用的特殊的内部时间戳类型,并且与常规Date类型无关。此内部时间戳记类型是64位值,其中:
由于BSON格式为低位优先,因此首先存储了最不重要的32位,但是mongod实例在所有平台上始终将先比较time_t值,在比较序数值,而不管字节顺序如何。
在一个mongod单实例中,时间戳值始终是唯一的。
在复本集中,操作日志(oplog)有一个ts字段。该字段值反映了BSON时间戳值的操作时间。
注意
BSON timestamp 类型是MongoDB内部使用。大多数情况下,在应用程序开发中,需要使用BSON date类型。更多信息,参考Date。
如果插入的文档包含带有空时间戳值的顶级字段时,MongoDB会将空时间戳值替换为当前时间戳值,但以下情况除外:如果_id字段本身包含空的时间戳值,则它将始终按原样插入并且不会被替换。
例:
插入有空时间戳值的文档:
db.test.insertOne( { ts: new Timestamp() } );
然后运行db.test.find()将返回一个文档(内容类似):
{ "_id" : ObjectId("542c2b97bac0595474108b48"), "ts" : Timestamp(1412180887, 1) }
mongodb服务已将ts的空timestamp值替换为插入时的timestamp值。
BSON Date是一个64位整数,代表自Unix纪元(1970年1月1日)到现在的毫秒数。这样可以追溯到过去和未来约2.9亿年的日期范围。
官方的BSON规范将BSON日期类型称为UTC日期。
BSON日期类型已签名。 [2]负值表示1970年之前的日期。
例如,在mongo shell中使用 new Date()函数创建Date:
var mydate1 = new Date()
例如,在mongo shell中使用ISODate()函数创建Date:
var mydate2 = ISODate()
例如,将日期值转成字符串:
mydate1.toString()
例如,返回日期值的月份值;月索引从零开始,因此一月是月份0:
mydate1.getMonth()
[2]在2.0版之前,Date值被误解为无符号整数,这会影响日期字段上的排序,范围查询和索引。由于升级时不会重新创建索引。因此,如果使用较早版本的Date值创建了索引,并且1970年之前的日期与你的应用程序相关,请重新索引。