数据类型
本页内容
MongoDB 使用BSON,它支持在JSON中不可用的附加数据类型。mongosh
壳在数据类型支持方面比传统的 mongo
壳要更好。
本文强调了 mongosh
和传统 mongo
壳之间类型使用的变更。有关受支持类型的更多信息,请参阅扩展 JSON 参考。
日期
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() 构造函数显式指定双精度浮点数
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
类型可能会被不一致地存储。
长
LongLong() 构造函数可以用于显式指定64位整数。
db.types.insertOne( { "_id": 3, "value": Long(1), "expectedType": "Long" } )
十进制128位
Decimal128() 的值是128位的基于十进制的小数浮点数,可以精确地模拟十进制舍入。
此功能适用于处理货币数据的应用,例如金融、税务和科学计算。
Decimal128
BSON类型使用IEEE 754 decimal128浮点数格式,支持34位小数(即有效数字)和指数范围从-6143到+6144。
db.types.insertOne( { "_id": 5, "value": Decimal128("1"), "expectedType": "Decimal128" } )
注意
要使用带有MongoDB驱动程序的Decimal128
数据类型,请确保使用支持它的驱动程序版本。
等价性和排序顺序
Decimal128
类型的值与其他数值类型根据其实际数值进行比较和排序。基于二进制的Double
类型的数值通常有基于十进制的值的近似表示,可能不等于它们的十进制表示。
时间戳
MongoDB在oplog中使用BSON时间戳。与Java时间戳类型类似,Timestamp
类型。对于涉及日期的操作,请使用日期类型。
Timestamp
签名有两个可选参数。
Timestamp( { "t": <integer>, "i": <integer> } )
参数 | 类型 | 默认值 | 定义 |
---|---|---|---|
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 }) } ]
创建自定义时间戳
使用自定义参数插入具有特定 时间戳
的多个文档。
此操作将三个文档插入到 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