(翻译) MongoDB(5) BSON类型

BSON是一个用来存储文档的二进制序列化格式,并且可以在MongoDB中远程调用。该BSON规范位于bsonspce.org

BSON在文档中支持下列数据类型作为值。每个数据类型都有相对应的数字和字符串别名用 $type 操作执行BSON类型来查询文档。

类型数字别名注意
Double1“double” 
String2“string” 
Object3“object” 
Array4“array” 
Binary data5“binData” 
Undefined6“undefined”已过时
ObjectId7“objectId” 
Boolean (布尔)8“bool” 
Date (日期)9“date” 
Null10“null” 
Regular Expression (正则表达式)11“regex” 
DBPointer12“dbPointer” 
JavaScript13“javascript” 
Symbol14“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 key127“maxKey” 

要确定字段的类型,请查看在Mongo Shell 中检验类型
如果你像转换BSON到JSON,请参阅JSON扩展

比较/排序

当比较不同BSON类型的值,MongoDB使用下面的比较顺序,从低到高:

  1. MinKey (内部类型)

  2. Null

  3. Numbers (ints, longs, doubles)

  4. Symbol, String(字符串)

  5. Object(对象)

  6. Array(数组)

  7. BinData

  8. ObjectId

  9. Boolean(布尔)

  10. Date(日期)

  11. Timestamp(时间戳)

  12. Regular Expression(正则表达式)

  13. MaxKey
    MongoDB对待一些类型是相等的,以便于比较。例如,数字类型在比较之前先进行转换。

3.0版本发生变化:Date对象在Timestamp对象之前。此前Date对象和Timestamp对象在同一等级。

比较一个不存在的字段,他可能是一个空的BSON对象。因此,在文档中一个字段排序,在文档{}{a: null}中字段排序,这两个文档在排序时将会被看成是等同的。

至于数组, 小于比较或者升序排序比较数组的最小元素,大于比较或者降序排序比较数组的最大元素. 因此,当比较的值是单元素数组(比如[1])和非数组字段(比如2)时, 结果在1小于2。空数组的比较(比如 [])当成没有null或者缺少字段的空数组。

MongoDB按照以下顺序对BinData排序:

  1. 首先, 数据的长度大小。

  2. 然后, BSON一个字节的子型。

  3. 最后,对于数据,进行逐字节比较。

以下各部分主要描述特定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…

    原文作者:魔王卷子
    原文地址: https://segmentfault.com/a/1190000006960389
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞