传统mongo
Shell 中的数据类型
警告
以下文档适用于 mongo
Shell,包含在 MongoDB Server 下载中。有关新 MongoDB Shell ( mongosh
) 的信息,请参阅mongosh 文档。
要了解这两个 Shell 之间的差异,请参阅mongo
shell和 mongosh
的比较。
MongoDB BSON提供对JSON以外的其他数据类型的支持。 驱动程序以主机语言为这些数据类型提供原生支持, mongo
shell还提供多个辅助类来支持在mongo
JavaScript shell中使用这些数据类型。 有关其他信息,请参阅扩展 JSON参考。
类型
Date
mongo
shell提供了多种方法返回日期,可以是string ,也可以是 Date
对象:
Date()
方法,以字符串形式返回当前日期。new Date()
构造函数,使用ISODate()
封装器返回Date
对象。ISODate()
构造函数,使用ISODate()
封装器返回Date
对象。
在内部,Date 对象存储为一个带符号的 64 位整数值,表示自 Unix 纪元(1970 年 1 月 1 日)以来的毫秒数。
并非所有数据库操作和驱动程序都支持完整的 64 位范围。可以安全地处理年份在 0
至 9999
(含)之间的日期。
以字符串形式返回日期
要以字符串形式返回日期,请使用Date()
方法,示例如下:
var myDateString = Date();
要打印变量的值,请在 shell 中键入变量名称,如下所示:
myDateString
结果是 myDateString
的值:
Wed Dec 19 2012 01:03:25 GMT-0500 (EST)
要验证类型,请使用 typeof
运算符,如下所示:
typeof myDateString
该操作会返回 string
。
返回 Date
mongo
shell 使用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")
要验证类型,请使用 instanceof
运算符,如下所示:
myDate instanceof Date myDateInitUsingISODateWrapper instanceof Date
对于两者,该操作都会返回true
。
ObjectId
mongo
shell 提供ObjectId数据类型的ObjectId()
包装器类。 要生成新的 ObjectId,请在mongo
shell 中使用以下操作:
new ObjectId
NumberLong
默认情况下, mongo
shell 将所有数字视为浮点值。 mongo
shell 提供了NumberLong()
包装器来处理64位整数。
NumberLong()
包装器接受 long 作为string :
NumberLong("2090845886852")
以下示例使用NumberLong()
包装器写入集合:
db.collection.insertOne( { _id: 10, calc: NumberLong("2090845886852") } ) db.collection.updateOne( { _id: 10 }, { $set: { calc: NumberLong("2555555000000") } } ) db.collection.updateOne( { _id: 10 }, { $inc: { calc: NumberLong("5") } } )
检索要验证的文档:
db.collection.findOne( { _id: 10 } )
在返回的文档中, calc
字段包含一个NumberLong
对象:
{ "_id" : 10, "calc" : NumberLong("2555555000005") }
如果使用$inc
将包含NumberLong
对象的字段的值递增float ,则数据类型将更改为浮点值,如以下示例所示:
使用
$inc
将calc
字段递增5
,mongo
shell 将其视为浮点数:db.collection.updateOne( { _id: 10 }, { $inc: { calc: 5 } } ) 检索更新后的文档:
db.collection.findOne( { _id: 10 } ) 在更新后的文档中,
calc
字段包含一个浮点值:{ "_id" : 10, "calc" : 2555555000010 }
注意
尽管 NumberLong()
构造函数接受来自mongo
shell的 integer
值(即 不带引号),不建议这样做。 指定大于 JavaScript 定义的Number.MAX_SAFE_INTEGER
(即数字2^53 - 1
)的整数值可能会导致意外行为。
NumberInt
默认情况下, mongo
shell 将所有数字视为浮点值。 mongo
shell 提供了NumberInt()
构造函数来显式指定32位整数。
NumberDecimal
版本 3.4 中的新增功能。
默认情况下, mongo
shell将所有数字视为 64 位浮点 double
值。 mongo
shell 提供NumberDecimal()
构造函数来显式指定128位基于十进制的浮点值,这些浮点值能够以精确的精度模拟十进制舍入。 此功能适用于处理货币数据的应用程序,例如金融、税务和科学计算。
decimal
BSON 类型使用 IEEE 754十进制128浮点数计数格式,该格式支持34十进制数字(即 有效数字),指数范围为 − 6143到 + 6144 。
NumberDecimal()
构造函数接受string形式的 decimal
值:
NumberDecimal("1000.55")
该值按如下方式存储在数据库中:
NumberDecimal("1000.55")
NumberDecimal()
构造函数还接受来自mongo
shell的 double
值(即 不带引号),但由于存在失去精度的风险,不建议这样做。 构造函数会为基于十进制的参数创建基于二进制的double
精度表示形式(可能会丢失精度),然后将该值转换为精度为15位的decimal
值。 以下示例将该值作为double
隐式传递,并显示了如何以15位精度创建该值:
NumberDecimal(1000.55)
该值按如下方式存储在数据库中:
NumberDecimal("1000.55000000000")
以下示例将该值作为double
隐式传递,并显示了如何发生精度损失:
NumberDecimal(9999999.4999999999)
该值按如下方式存储在数据库中:
NumberDecimal("9999999.50000000")
注意
要在MongoDB 驱动程序中使用decimal
数据类型,请务必使用支持该类型的驱动程序版本。
相等和排序顺序
decimal
类型的值会根据其实际数值与其他数值类型进行比较和排序。 基于二进制的double
类型的数值通常具有基于十进制的值的近似表示形式,并且可能不完全等于其decimal
表示形式,因此在检查decimal
值的相等性时使用NumberDecimal()
构造函数。 请考虑以下示例,其中包含numbers
集合中的以下文档:
{ "_id" : 1, "val" : NumberDecimal( "9.99" ), "description" : "Decimal" } { "_id" : 2, "val" : 9.99, "description" : "Double" } { "_id" : 3, "val" : 10, "description" : "Double" } { "_id" : 4, "val" : NumberLong("10"), "description" : "Long" } { "_id" : 5, "val" : NumberDecimal( "10.0" ), "description" : "Decimal" }
将下表中的查询代入db.numbers.find(<query>)
方法时,会返回以下结果:
查询 | 结果 |
---|---|
{ "val": 9.99 } | { " _id ": 2, "val": 9.99, "description": " double " } |
{ "val": NumberDecimal( " 9.99 " ) } | { "_id": 1 , "val": NumberDecimal( " 9.99 " ), "description": "Decimal" } |
{ val: 10 } | { "_id": 3, "val": 10, "description": "Double" } { "_id": 4, "val": NumberLong(10), "description": "Long" } { "_id": 5, "val": NumberDecimal( "10.0" ), "description": "Decimal" } |
{ val: NumberDecimal( " 10 " ) } | { "_id": 3, "val": 10, "description": "Double" } { "_id": 4, "val": NumberLong(10), "description": "Long" } { "_id": 5, "val": NumberDecimal( "10.0" ), "description": "Decimal" } |
第一个查询{ "val": 9.99 }
隐式搜索9.99
的double
表示形式,该表示形式不等于该值的decimal
表示形式。
NumberDecimal()
构造函数用于查询具有9.99
的decimal
表示形式的文档。 double
类型的值被排除,因为它们与9.99
的decimal
表示的确切值不匹配。
查询整数时,会返回所有数字类型的匹配值。 例如,查询10
的double
表示形式将在结果中包含10.0
的decimal
表示形式,反之亦然。
检查decimal
类型
要测试decimal
类型,请使用带有$type
string别名"decimal"
或19
( 类型的数字代码)的decimal
操作符。
db.inventory.find( { price: { $type: "decimal" } } )
检查mongo
Shell 中的类型
为了确定字段的类型, mongo
shell 提供了instanceof
和typeof
操作符。
instanceof
instanceof
返回一个布尔值,以测试某个值是否为某种类型的实例。
例如,以下操作测试_id
字段是否为类型ObjectId
的实例:
mydoc._id instanceof ObjectId
该操作会返回 true
。
typeof
typeof
返回字段的类型。
例如,以下操作会返回_id
字段的类型:
typeof mydoc._id
在这种情况下, typeof
将返回更通用的object
类型,而不是ObjectId
类型。