当前位置: 首页 > 工具软件 > BSON > 使用案例 >

【MongoDB】BSON类型

秦鸿羽
2023-12-01

目录

一、ObjectId

二、字符串(String)

三、时间戳(Timestamps)

四、日期(Date)


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还支持类型编号的别名,该别名与integer, decimal, double,  long BSON类型匹配。
  • $ type聚合运算符返回其参数的BSON类型。
  • 如果$ isNumber聚合运算符的参数为BSON类型integer, decimal, double,  long.则返回true。(New in version 4.4)

注:$ type用于筛选字段值是指定的BSON type(s)类型的文档。例如:

{ field: { $type: <BSON type> } }

{ field: { $type: [ <BSON type1> , <BSON type2>, ... ] } }

要查看字段类型,请参阅mongo Shell检查字段类型

将BSON转换为JSON,请参阅MongoDB扩JSON

以下各节描述了BSON类型需要特别注意的事项。

 

一、ObjectId

ObjectId比较小,还是唯一的,可以快速生成并排序。ObjectId值的长度为12个字节,包括:

  • 4字节的时间戳(自Unix时代以来以秒为单位的时间戳值),代表ObjectId的创建
  • 5字节的随机值
  • 3字节的递增计数器,初始化值是随机值

虽然BSON格式本身是低位字节序,但时间戳和计数器值却是高位字节序,最有效字节出现在字节序列前端。

字节序,顾名思义字节的顺序,就是大于一个字节类型的数据在内存中的存放顺序(一个字节的数据当然就无需谈顺序的问题了)。

字节序分为两类:Big-Endian和Little-Endian,定义如下:

a) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

c) 网络字节序:TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序。

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

同理,通过upserttrue更新操作插入的文档时,若_id字段省略,也自动生成。

MongoDB客户端应添加一个唯一ObjectId值的_id字段。在_id字段中使用ObjectIds具有以下额外优点:

  • 通过mongo shell,可以使用ObjectId.getTimestamp()方法查看ObjectId的创建时间。
  • 在存储ObjectId值的_id字段上进行排序大致相当于按创建时间进行排序。

重要提示

尽管ObjectId值应随时间增加,但不一定是单调的。这是因为他们:

  • ObjectId仅包含秒级时间戳,因此在同一秒内创建的ObjectId值没有保证的顺序
  • 由客户端生成,客户端可能具有不同的系统时钟。

参考资料:ObjectId()

 

二、字符串(String)

BSON字符串是UTF-8编码。

通常,在对BSON进行序列化和反序列化时,每种编程语言的驱动程序都会从该语言的字符串格式转换为UTF-8。这样就可以轻松地将大多数国际字符存储在BSON字符串中。 [1]此外,MongoDB $ regex查询在regex字符串中支持UTF-8。

[1]对于一个UTF-8字符集的字符串,对字符串使用sort()是合理的。但是,由于内部sort()使用C ++ strcmp api,因此排序顺序可能会错误地处理某些字符。

 

三、时间戳(Timestamps)

BSON有一种在MongoDB使用的特殊的内部时间戳类型,并且与常规Date类型无关。此内部时间戳记类型是64位值,其中:

  • 最重要的32位是time_t值(自Unix时代以来的秒数)
  • 最不重要的32位是某1秒内操作的递增序数

由于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值。

 

四、日期Date

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年之前的日期与你的应用程序相关,请重新索引。

 类似资料: