数据类型
在此页面上
MongoDB 使用 BSON 来存储数据,它支持 JSON 中没有的其他数据类型。与旧版的 mongo
shell 相比,mongosh
shell 对驱动程序的数据类型支持更好。
本文档重点介绍了 mongosh
和旧版 mongo
shell 之间类型使用的变化。有关支持类型的更多信息,请参阅扩展 JSON参考资料。
Date
mongosh
提供多种方法返回日期,可以是字符串,也可以是 Date
对象:
Date()
方法,以字符串形式返回当前日期。new Date()
构造函数,使用ISODate()
封装器返回Date
对象。ISODate()
构造函数,使用ISODate()
封装器返回Date
对象。
ObjectId
mongosh
提供围绕 ObjectId 数据类型的 ObjectId()
包装器类别。要生成新的 ObjectId,请使用 mongosh
中的以下操作:
new ObjectId
从 1.8.0 开始, ObjectId
包装器不再接受:
ObjectId.prototype.generate
ObjectId.prototype.getInc
ObjectId.prototype.get_inc
ObjectId.getInc
double
Double() 构造函数可用于显式指定 double 值:
db.types.insertOne( { "_id": 2, "value": Double(1), "expectedType": "Double" } )
注意
如果字段的值是可以转换为 32 位整数的数字,mongosh
会将其存储为 Int32
。如果不是,则 mongosh
默认将该数字存储为 Double
。要指定值类型,请使用 Double()
或 Int32()
构造函数。
Int32
Int32() 构造函数可用于明确指定 32 位整数。
db.types.insertOne( { "_id": 1, "value": Int32(1), "expectedType": "Int32" } )
警告
如果您同时使用 mongosh
和传统mongo
shell 连接到同一集合,则默认的 Int32
和Double
类型的存储方式可能会不一致。
Long
Long() 构造函数可用于显式指定 64 位整数。
db.types.insertOne( { "_id": 3, "value": Long(1), "expectedType": "Long" } )
Decimal128
Decimal128() 的值为基于十进制的 128 位浮点数,它们模拟了精确的十进制舍入。
此功能适用于处理货币数据(例如财务、税收和科学计算)的应用程序。
Decimal128
BSON 类型使用 IEEE 754 十进制 128 浮点编号格式,支持 34 个十进制数字(即 有效数字),指数范围为 −6143 到 +6144。
db.types.insertOne( { "_id": 5, "value": Decimal128("1"), "expectedType": "Decimal128" } )
注意
要将 Decimal128
数据类型与 MongoDB 驱动程序结合使用,请务必使用支持该数据类型的驱动程序版本。
相等和排序顺序
Decimal128
类型的值会根据其实际数值与其他数值类型进行比较和排序。基于二进制的 Double
类型的数值通常采用基于十进制的值的近似表示形式,且可能不完全等于其十进制表示形式。
时间戳
MongoDB 在 oplog 内部使用 BSON 时间戳。Timestamp
类型的工作方式与 Java Timestamp 类型类似。使用日期类型执行日期相关操作。
Timestamp
签名具有两个可选参数。
Timestamp( { "t": <integer>, "i": <integer> } )
Parameter | 类型 | 默认 | 定义 |
---|---|---|---|
t | 整型 | 自 UNIX 纪元起的当前时间。 | 可选。 以秒为单位的时间。 |
i | 整型 | 1 | 可选。 用于在给定秒数内有多个操作时进行排序。如果不使用 t ,则i 不起作用。 |
类型检查
使用 $type
查询操作符或检查对象构造函数来确定类型。
Javascript typeof
操作符返回通用值,例如number
或object
,而不是更具体的Int32
或ObjectId
。
Javascript 的instanceof
操作符不可靠。例如,instanceof
将服务器响应中的 BSON 值分配给与用户提供的值不同的基类。
有关用法示例,请参阅使用 $type()
进行类型检查和使用构造函数进行类型检查。
示例
以字符串形式返回日期
要以字符串形式返回日期,请使用Date()
方法,示例如下:
var myDateString = Date();
要打印变量的值,请在 shell 中键入变量名称,如下所示:
myDateString
结果是 myDateString
的值:
Wed Dec 19 2012 01:03:25 GMT-0500 (EST)
要验证类型,请使用 typeof
运算符,如下所示:
typeof myDateString
该操作会返回 string
。
返回 Date
mongosh
使用 ISODate
辅助程序包装Date
类型的对象;但是,对象仍然是 Date
类型。
以下示例同时使用 new Date()
构造函数和 ISODate()
构造函数返回 Date
对象。
var myDate = new Date(); var myDateInitUsingISODateWrapper = ISODate();
您也可以将 new
操作符与 ISODate()
构造函数结合使用。
要打印变量的值,请在 shell 中键入变量名称,如下所示:
myDate
结果是,myDate
的 Date
值封装在 ISODate()
辅助函数中:
ISODate("2012-12-19T06:01:17.171Z")
要验证类型:
var myDate = ISODate("2021-03-21T06:00:00.171Z") Object.prototype.toString.call(myDate) === "[object Date]"
该操作会返回 true
。
数值类型
考虑 types
集合。
{ _id: 1, value: 1, expectedType: 'Int32' }, { _id: 2, value: Long("1"), expectedType: 'Long' }, { _id: 3, value: 1.01, expectedType: 'Double' }, { _id: 4, value: Decimal128("1.01"), expectedType: 'Decimal128' }, { _id: 5, value: 3200000001, expectedType: 'Double' }
此表显示相应<QUERY>
的db.types.find( <QUERY> )
命令的结果。类型名称和别名在 BSON 类型页面上显示。
查询 | 结果 | |||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||||||||||||||||||||||||
|
| |||||||||||||||||||||||||||||||
|
| |||||||||||||||||||||||||||||||
|
| |||||||||||||||||||||||||||||||
|
| |||||||||||||||||||||||||||||||
|
| |||||||||||||||||||||||||||||||
|
|
查询 { "value": 1.01 }
隐式搜索 1.01
的 Double
表示形式。文档 _id: 4
是一个 Decimal128
,因此未被选中。
但请注意,{ "value": 1 }
同时返回 Int32
和 Long
类型。
默认数字类型一致性
考虑 typeExample
集合。该集合由两个相同的文档 { "a": 1 }
组成。第一个文档是在传统 mongo
Shell 中创建的,第二个文档是在 mongosh
中创建的。
我们可以在聚合管道中使用 $type
操作符来查看在每个 shell 中分配的类型。
db.typeExample.aggregate( [ { $project: { "valueType": { "$type": "$a" }, "_id": 0 } } ] )
在传统 mongo
shell 中创建的第一个文档中,该值存储为 double
。在 mongosh
文档中,该值存储为类型 int
。
[ { valueType: 'double' // inserted in legacy mongo shell }, { valueType: 'int' // inserted in mongosh } ]
为新文档添加时间戳
使用不带参数的 Timestamp()
以使用默认设置插入多个文档:
db.flights.insertMany( [ { arrival: "true", ts: Timestamp() }, { arrival: "true", ts: Timestamp() }, { arrival: "true", ts: Timestamp() } ] )
运行 db.flights.find({})
以查看时间戳。请注意,即使所有三个条目都在同一秒内标记,但每个条目的间隔都会增加。
[ { _id: ObjectId("6114216907d84f5370391919"), arrival: 'true', ts: Timestamp({ t: 1628709225, i: 1 }) }, { _id: ObjectId("6114216907d84f537039191a"), arrival: 'true', ts: Timestamp({ t: 1628709225, i: 2 }) }, { _id: ObjectId("6114216907d84f537039191b"), arrival: 'true', ts: Timestamp({ t: 1628709225, i: 3 }) } ]
创建自定义时间戳
使用自定义参数插入具有特定 Timestamp
的多个文档。
此操作将三个文档插入到 flights
集合中,并使用 UNIX 纪元值 1627811580
将 ts
时间设置为 2021 年 8 月 1 日 9:53 GMT。
db.flights.insertMany( [ { arrival: "true", ts: Timestamp(1627811580, 10) }, { arrival: "true", ts: Timestamp(1627811580, 20) }, { arrival: "true", ts: Timestamp(1627811580, 30) } ] )
生成的文档如下所示:
[ { _id: ObjectId("6123d8315e6bba6f61a1031c"), arrival: 'true', ts: Timestamp({ t: 1627811580, i: 10 }) }, { _id: ObjectId("6123d8315e6bba6f61a1031d"), arrival: 'true', ts: Timestamp({ t: 1627811580, i: 20 }) }, { _id: ObjectId("6123d8315e6bba6f61a1031e"), arrival: 'true', ts: Timestamp({ t: 1627811580, i: 30 }) } ]
类型检查 $type()
$type
查询操作符接受字符串别名或与数据类型对应的数字代码。有关 BSON 数据类型及其对应数字代码的列表,请参阅 BSON 类型。
例如,对 Decimal128
类型的这些检查是等效的:
db.types.find( { "value": { $type: "decimal" } } ) db.types.find( { "value": { $type: 19 } } )
使用构造函数进行类型检查
检查对象 constructor
以确定类型。例如,db.collection.find()
的输出是 Cursor
。
var findResults = db.housing.find({"multiUnit": true} ) findResults.constructor.name // Returns the type