BSON是Mongo用于存储文档和远程过程调用的一种二进制序列化格式。有关BSON的规定在于bsonspec.org
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 16 int
Timestamp 17 timestamp
64-bit integer 18 long
Decimal128 19 decimal 3.4版本新加
Min key -1 minKey
Max key 127 maxKey
一些特别的BSON类型的介绍:
(1)ObjectId
ObjectId的特点就是小,惟一,能够快速生成,有序。
ObjectId是以其创建时时戳的四字节为首的由12字节组成的值,规则如下:
A、4字节的时间戳
B、3字节的机器标识符
C、2字节的进程ID
D、3字节的计数器,由一个随机数开始
在Mongo中,存储在集合中的每个文档都需要一个惟一的_id域作为主键。如果插入操作时遗漏了_id域,Mongo
会自动给_id域生成一个ObjectId
使用ObjectId作为_id域的值有以下好处:
A、在Mongo Shell中,可以通过ObjectId访问创建时间,调用ObjectId.getTimeStamp()方法。
B、ObjectId的排序相当于创建时间的排序。
(2)String
BSON字符串使用UTF-8编码。通常情况下,每种编程语言的驱动都会在序列化和反序列化BSON时将编程语言的编码
转换为UTF-8.这种机制使得BSON字符串可以容易的存储国际化的字符。
一个使用UTF-8编码的字符串,使用对String排序的sort方法理论上结果是正确的。但是,因为内部使用C++ 的
strcmp方法,排列顺序可以会出现一些错误。
(3)Timestamps
BSON中有一种特殊的timestamp类型用于内部的MongoDB使用,并且与常规的Date完全没有联系。Timestamp的值是
一个64位的值,包括32位的一个time_t 值(即从1970年到现在经过的秒数)和另一个32位的给定时间内操作的自
增序数。
在单一Mongo实例中,timestamp 值总是惟一的。
在复制操作中,oplog持有一个叫ts的域,这个域的值用来表示操作时间,使用就是BSON timestamp类型的值。
oplog:是一个存储有序的Mongo逻辑写历史的可变集合。是Mongo实现复制机制的基础构件。
如果插入一个档时,存在顶层域为空的timestamp值,MongoDB服务会用当前时间戳替换那个空的时间戳。例如:
如果插入文档一个timestamp值,如下操作:
var a = new Timestamp();
db.test.insertOne({ts:a});
此时,db.test().find()操作会返回文档描述如下:
{ "_id" : ObjectId("542c2b97bac0595474108b48"), "ts" : Timestamp(1412180887, 1) }
但是,如果ts域位于内嵌的文档中时,则还会以空值存储。
2.6版本之前,只会处理插入文档的包含_id在内的前两个域中的空timestamp值,之后,则只要是顶层域都会处理
空的timestamp值。
(4)Date
BSON日期是一个表示从1970年1月1日到今的毫秒数的64位的整数,可表示大约2亿9千万年的过去和未来。
BSON Date类型是有符号的,负值表示1970年以前。
几个BSON Date类型的例子:
var mydate1 = new Date()//在Mongo Shell中用构造函数构造日期对象。
var mydate2 = ISODate()//初始化一个ISO格式日期
mydate1.toString()//将日期类型转换成字符串类型
mydate1.getMonth()//返回日期中月份,月份从0开始
在2.0版本以前,日期值被错误的解释为无符号整数,这影响了排序,范围查询,和日期类型域上创建的索引。因为
升级的时候索引不会重建。如果是早期版本日期域上创建的索引,请重新创建。