BSON是一个用来存储文档的二进制序列化格式,并且可以在MongoDB中远程调用。该BSON规范位于bsonspce.org。
BSON在文档中支持下列数据类型作为值。每个数据类型都有相对应的数字和字符串别名用 $type 操作执行BSON类型来查询文档。
类型 | 数字 | 别名 | 注意 |
---|---|---|---|
Double | 1 | “double” | |
String | 2 | “string” | |
Object | 3 | “object” | |
Array | 4 | “array” | |
Binary data | 5 | “binData” | |
Undefined | 6 | “undefined” | 已过时 |
ObjectId | 7 | “objectId” | |
Boolean (布尔) | 8 | “bool” | |
Date (日期) | 9 | “date” | |
Null | 10 | “null” | |
Regular Expression (正则表达式) | 11 | “regex” | |
DBPointer | 12 | “dbPointer” | |
JavaScript | 13 | “javascript” | |
Symbol | 14 | “symbol” | |
JavaScript (with scope) | 15 | “javascriptWithScope” | |
32-bit integer (32位整数) | 16 | “int” | |
Timestamp (时间戳) | 17 | “timestamp” | |
64-bit integer (32位整数) | 18 | “long” | |
Min key | -1 | “minKey” | |
Max key | 127 | “maxKey” |
要确定字段的类型,请查看在Mongo Shell 中检验类型。
如果你像转换BSON到JSON,请参阅JSON扩展。
比较/排序
当比较不同BSON类型的值,MongoDB使用下面的比较顺序,从低到高:
MinKey (内部类型)
Null
Numbers (ints, longs, doubles)
Symbol, String(字符串)
Object(对象)
Array(数组)
BinData
ObjectId
Boolean(布尔)
Date(日期)
Timestamp(时间戳)
Regular Expression(正则表达式)
MaxKey
MongoDB对待一些类型是相等的,以便于比较。例如,数字类型在比较之前先进行转换。
3.0版本发生变化:Date对象在Timestamp对象之前。此前Date对象和Timestamp对象在同一等级。
比较一个不存在的字段,他可能是一个空的BSON对象。因此,在文档中一个字段排序,在文档{}
和{a: null}
中字段排序,这两个文档在排序时将会被看成是等同的。
至于数组, 小于比较或者升序排序比较数组的最小元素,大于比较或者降序排序比较数组的最大元素. 因此,当比较的值是单元素数组(比如[1]
)和非数组字段(比如2
)时, 结果在1
小于2
。空数组的比较(比如 []
)当成没有null
或者缺少字段的空数组。
MongoDB按照以下顺序对BinData
排序:
首先, 数据的长度大小。
然后, BSON一个字节的子型。
最后,对于数据,进行逐字节比较。
以下各部分主要描述特定BSON类型的特殊注意事项。
ObjectId
ObjectIds 是小的,唯一的,快速生成的,可排序的。 ObjectId 值由12个字节组成,其中ObjectId的前四个字节能够表现出一个创建的时间戳,特别是:
一个4字节的代表Unix纪元以来的所有秒数的值
一个3字节的机器标识符
一个2字节的进程ID
一个3字节的计数器,包含一个随机值
在MongoDB中, 在一个集合中存储文档需要一个唯一的_id字段来充当主键。如果在文档中未指定_id字段,MongoDB会使用ObjectId作为_id
字段的默认值;例如:如果一个文档在插入的时候顶级字段不包含_id
,Mongodb驱动会增加一个包含ObjectId的_id
字段。
此外,如果mongod接收到的要插入的文档并不包含_id
字段(例如通过更新操作执行upsert选项), mongod将会在文档的开头添加一个值为ObjectId的_id
字段。
MongoDB 客户端应该添加一个带有唯一的ObjectId值的_id
字段。使用 ObjectId 作为_id
字段提供了以下额外的好处:
在Mongo Shell中,你可以访问
ObjectId
的创建时间,使用ObjectId.getTimestamp()模块。在存储
ObjectId
值的_id
字段上排序,大致相当于通过创建时间排序。
重要:
ObjectId
值和生成时间的顺序关系在一秒内并不是完全一致的。如果多个系统, 或者多个进程或者线程在单一系统生成的一秒内的值;ObjectId
值并不表示一个严格的插入顺序。 不同客户端间的时钟偏移也可以导致一个非严格的值的排序,因为值是不同客户端之间产生的ObjectId
值。另请参阅:ObjectId()
String
BSON字符串是UTF-8。一般来说,当序列化和反序列化BSON时,每个编程语言的驱动都会从语言的字符串格式转化为UTF-8格式。 这使得能够非常容易的在BSON中存储大多数国际字符。[1] 此外, MongoDB $regex 查询在正则表达式字符串时支持UTF-8。
[1]考虑到字符串使用UTF-8字符集,在字符串上使用sort()将是非常合理的。然而,因为内部sort()使用C++ strcmp api,在处理某些字符的排序的时候可能顺序会不正确。
Timestamps
BSON 在MongoDB中使用一个特定的时间戳类型,并且不
与常规的Date类型相关联。时间戳的值是一个64位的值,其中:
第32位是一个
time_t
值 (自Unix纪元的秒数)第二个32位是一个在给定的秒内操作
顺序
递增的。
在单台mongod实例中,时间戳值总是唯一的。
在复制时,oplog有一个ts
字段。这个字段的使用了BSON时间戳的值反映了操作时间。
注意: MongoDB中内部使用BSON 时间戳类型。在大多数情况下,在应用程序中开发,你将希望使用BSON时间类型。查看Date获取更新信息。
如果你插入一个包含顶级字段中包含一个空的BSON时间戳文档,MongoDB服务器会将空的时间戳替换为当前时间戳的值。例如,如果你创建一个插入带有时间戳的文档,在下面的插入操作中:
var a = new Timestamp();
db.test.insert( { ts: a } );
然后,db.test.find()操作将会一个类似下面的文档:
{ "_id" : ObjectId("542c2b97bac0595474108b48"), "ts" : Timestamp(1412180887, 1) }
如果ts
是内嵌文档的一个字段,服务器将会把它作为一个空的时间戳值。
2.6版本发生改变:在此之前, 服务器只会在插入文档的第一二个字段替换空的时间戳值,包含_id
字段。现在MongoDB将只会替换顶级字段。
Date
BSON Date 是64位整数,代表自Unix纪元(1997年1月1日)以来的毫秒数。 这个结果的可表示日期范围是在过去和将来总共 2.9亿年。
官方BSON风格指定BSON的Date类型为UTC时间。
BSON Date 类型是有符号的。[2] 负值表示1970年之前的日期。
示例:
在 Mongo Shell中使用new Date()
来构造一个Date
对象:
var mydate1 = new Date()
在 Mongo Shell 中使用ISODate()
来构造一个Date
对象:
var mydate2 = ISODate()
将Date
的值作为字符串返回:
mydate1.toString()
返回Date
值的月份部分;月份是从0开始索引,所以一月份是0:
mydate1.getMonth()
[2]在2.0版本之前,Date
值被错误的解释为无符号整数,这影响了排、范围查询和Date
字段的索引。如果你在更早的版本中创建Date
字段上创建了一个索引,因为升级的时候不会创建索引,请重新创建, 在1070年之前的日期是跟你的应用相关的。
下一章:https://segmentfault.com/a/11…
本文地址:https://docs.mongodb.com/manu…