英文原文地址:https://docs.mongodb.com/manual/core/shell-types/
MongoDB BSON 提供了比 JSON 更多的数据类型支持。驱动程序在主机语言中为这些数据类型提供了本机支持,Mongo Shell 还提供了几个帮助类,以支持在 Mongo JavaScript Shell 中使用这些数据类型。
Mongo Shell 提供了各种方法来返回日期,既可以是字符串,也可以是日期对象:
Date() 方法,该方法将当前日期作为字符串返回。
new Date() 构造函数,它使用 ISODate() 包装器返回日期对象。
ISODate() 构造函数,它使用ISODate()包装器返回日期对象。
在内部,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
操作返回字符串。
Mongo Shell用 ISODate 助手包装日期类型的对象;但是,对象仍然是 Date 类型。下面的示例使用 new Date() 构造函数和 ISODate() 构造函数返回 Date 对象。
var myDate = new Date(); var myDateInitUsingISODateWrapper = ISODate();
您也可以在 ISODate() 构造函数中使用新操作符。要打印变量的值,请在 shell 中键入变量名,如下所示:
myDate
结果是封装在 ISODate() 助手中的 myDate 的日期值:
ISODate("2012-12-19T06:01:17.171Z")
若要验证类型,请使用 instanceof 运算符,如下所示:
myDate instanceof Date myDateInitUsingISODateWrapper instanceof Date
操作都返回true。
Mongo Shell提供了围绕 Objectid 数据类型的 objectId() 包装类。要生成一个新的 ObjectId,在 Mongo Shell 中使用以下操作:
new ObjectId
Mongo Shell 默认将所有数字视为浮点值。Mongo Shell 提供 NumberLong() 包装器来处理64位整数。NumberLong() 包装器接受长字符串:
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 对象的字段的值,则数据类型将更改为浮点值,如以下示例所示:
使用 $inc 将 calc 字段增加 5,mongo shell 将其视为浮点数:
db.collection.updateOne( { _id: 10 }, { $inc: { calc: 5 } } )
检索更新后的文件:
db.collection.findOne( { _id: 10 } )
在更新的文档中,calc 字段包含一个浮点值:
{ "_id" : 10, "calc" : 2555555000010 }
mongo shell 默认将所有数字视为浮点值。mongo shell 提供了 NumberInt() 构造函数来显式指定 32 位整数。
[新版本3.4] mongo shell 默认将所有数字视为 64 位浮点 double。mongo shell 提供了 NumberDecimal() 构造函数来显式指定 128 位基于十进制的浮点值,能够精确地模拟十进制舍入。此功能用于处理货币数据 (如金融、税收和科学计算) 的应用程序。
十进制 BSON 类型使用 IEEE 754 小数 128 浮点编码格式,它支持 34 位小数 (即有效位) 和指数范围为 −6143 至 +6144。
NumberDecimal() 构造函数接受十进制值作为字符串:
NumberDecimal("1000.55")
该值存储在数据库中,如下所示:
NumberDecimal("1000.55")
NumberDecimal() 构造函数还接受来自 mongo shell 的 double (即不带引号),但由于可能会丢失精度,因此不建议这样做。构造函数为基于十进制的参数创建基于二进制的双精度表示 (可能会丢失精度),然后将该值转换为精度为 15 位的十进制值。下面的示例将该值隐式地作为 Double 传递,并演示如何以 15 位的精度创建该值:
NumberDecimal(1000.55)
该值存储在数据库中,如下所示:
NumberDecimal("1000.55000000000")
下面的示例将该值隐式地作为 Double 传递,并说明如何发生精度损失:
NumberDecimal(9999999.4999999999)
该值存储在数据库中,如下所示:
NumberDecimal("9999999.50000000")
注意:若要在 MongoDB 驱动程序中使用十进制数据类型,请确保使用支持它的驱动程序版本。
十进制类型的值与其他数字类型根据其实际数值进行比较和排序。基于二进制的 double 类型的数值通常有十进制值的近似表示,并且可能与它们的十进制表示形式不完全相等,所以在检查十进制值的相等时使用 NumberDecimal() 构造函数。考虑数字集合中的下列文档示例:
{ "_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} 隐式地搜索不等于该值的十进制表示的 9.99 的 double 表示形式。
NumberDecimal() 构造函数用于查询带有 9.99 小数表示的文档。double 类型的值被排除在外,因为它们不匹配十进制表示形式 9.99 的确切值。
查询整数时,将返回所有数字类型的匹配值。例如,查询 10 的 double 表示将包括结果中的十进制表示为 10.0,反之亦然。
若要测试十进制(decimal )类型,请使用带有字符串别名 “decimal” 或 19 (十进制类型的数字代码) 的 $type 运算符。
db.inventory.find( { price: { $type: "decimal" } } )
要确定字段的类型,mongo shell 提供 instanceof 和 typeof 操作符。
instanceof 返回一个布尔值来测试某个值是否是某种类型的实例。例如,以下操作测试 _id 字段是否是 ObjectId 类型的实例:
mydoc._id instanceof ObjectId
操作返回true。
typeof 返回字段的类型。例如,以下操作返回_id字段的类型:
typeof mydoc._id
在这种情况下,typeof 将返回更一般的 object 类型,而不是 ObjectId 类型。