# mongo Shell中的数据类型

**在本页面**

* [类型](#类型)
  * [Date](#date)
  * [ObjectId](#objectid)
  * [NumberLong](#numberlong)
  * [NumberInt](#numberint)
  * [NumberDecimal](#decimal)
* [在mongo Shell中检查类型](#检查)
  * [instanceof](#instanceof)
  * [typeof](#typof)

> **\[success] Note**
>
> 下面的文档是[MongoDB服务器下载](https://www.mongodb.com/try/download/community?tck=docs_server).中包含的[`mongo`](https://docs.mongodb.com/master/reference/program/mongo/#bin.mongo) shell。有关新的MongoDB Shell ，**mongosh**的信息，请参考[mongosh文档](https://docs.mongodb.com/mongodb-shell/)。
>
> 要了解这两种shell的区别，请参阅[Comparison of the mongo Shell and mongosh](https://docs.mongodb.com/master/mongo/#compare-mongosh-mongo).

\*\*MongoDB [BSON](https://docs.mongodb.com/master/reference/glossary/#term-bson) 支持除JSON本身支持类型之外的其他数据类型。 驱动程序以宿主语言为这些数据类型提供本机支持，而[`mongo`](https://docs.mongodb.com/master/reference/program/mongo/#bin.mongo)shell还提供了一些帮助程序类来支持在[`mongo`](https://docs.mongodb.com/master/reference/program/mongo/#bin.mongo) JavaScript shell中使用这些数据类型。 有关更多信息，请参阅[Extended JSON](https://docs.mongodb.com/master/reference/mongodb-extended-json/)引用。

## **类型**

### Date

[`mongo`](https://docs.mongodb.com/master/reference/program/mongo/#bin.mongo) shell提供了多种返回日期的方法，这些方法可以是字符串，也可以是**Date**对象：

* **Date()** 方法，以字符串形式返回当前日期。
* **new Date()** 构造函数，该构造函数使用`ISODate()`包装器返回Date对象。
* **ISODate()** 构造函数，该构造函数使用`ISODate()`包装器返回Date对象。

  ​

在内部，[Date](https://docs.mongodb.com/master/reference/bson-types/#document-bson-type-date)对象存储为带符号的64位整数，表示自Unix纪元（1970年1月1日）以来的毫秒数。 并非所有的数据库操作和驱动程序都支持完整的64位范围。 您可以安全地处理年份，年份范围在**0**到**9999**之间。\
**以字符串类型返回日期**

以字符串类型返回日期，要用到\*\*Data()\*\*方法，如下所示：

```
var myDateString = Date();
```

要打印变量的值，请在shell中键入变量名称，如下所示：

```
myDateString
```

**myDataString**值的结果如下：

```
Wed Dec 19 2012 01:03:25 GMT-0500 (EST)
```

要验证类型，请使用**typeof**运算符，如下所示：

```
typeof myDateString
```

该操作返回值为 **String**

**Return Date**

[`mongo`](https://docs.mongodb.com/master/reference/program/mongo/#bin.mongo) shell使用`ISODate`帮助程序包装Date类型的对象； 但是，对象仍为日期类型。

下面的示例使用新的\*\*Date()**构造函数和**ISODate()\*\*构造函数来返回Date对象。

```
var myDate = new Date();
var myDateInitUsingISODateWrapper = ISODate();
```

您也可以将**new**运算符与\*\*ISODate()\*\*构造函数一起使用。\
要打印变量的值，请在shell中键入变量名称，如下所示：

```
myDate
```

结果是包装在**ISODate()** 帮助器中的**myDate**的**Date**值：

```
ISODate("2012-12-19T06:01:17.171Z")
```

要验证类型，请使用**instanceof**运算符，如下所示：

```
myDate instanceof Date
myDateInitUsingISODateWrapper instanceof Date
```

这两个操作均返回`true`

### **ObjectID**

mongo shell提供了围绕[**ObjectId**](https://docs.mongodb.com/master/reference/bson-types/#objectid) \*\*\*\*数据类型的\*\*ObjectId()\*\*封装类。 要生成新的ObjectId，请在mongo shell中使用以下操作：

```
new ObjectId
```

参考：[ObjectId](https://docs.mongodb.com/manual/reference/method/ObjectId/#ObjectId)

### **NumberLong**

mongo shell默认情况下会将所有数字视为浮点型。mongo shell提供了**NumberLong()** 包装器来处理64位整数。

**NumberLong()** 封装接受long作为字符串：

```
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`](https://docs.mongodb.com/master/reference/operator/update/inc/#up._S_inc)通过浮点数递增包含**NumberLong**对象的字段的值，则数据类型将更改为浮点值，如以下示例所示：

1.使用[`$inc`](https://docs.mongodb.com/master/reference/operator/update/inc/#up._S_inc) 将**calc**字段增加 **5**，[`mongo`](https://docs.mongodb.com/master/reference/program/mongo/#bin.mongo) shell将其视为浮点数：

```
db.collection.updateOne( { _id: 10 },
                            { $inc: { calc: 5 } } )
```

2.检索更新的文档：

```
db.collection.findOne( { _id: 10 } )
```

在更新的文档中，calc字段包含一个浮点值：

```
{ "_id" : 10, "calc" : 2555555000010 }
```

### **NumberInt**

mongo shell默认情况下会将所有数字视为浮点值。 mongo shell提供\*\*NumberInt()\*\*构造函数来显式指定32位整数。

### **NumberDecimal**

**始于3.4版本**\
mongo shell默认将所有数字视为64位浮点双精度值。 mongo shell提供了\*\*NumberDecimal()\*\*构造函数来显式指定基于128位的基于十进制的浮点值，该值能够精确地模拟十进制舍入。 此功能适用于处理货币数据的应用程序，例如金融、税收和科学计算。\
十进制BSON类型使用IEEE 754十进制128浮点编号格式，该格式支持34个十进制数字（即有效数字）和-6143至+6144的指数范围。\
NumberDecimal（）构造函数接受十进制值作为字符串：

```
NumberDecimal("1000.55")
```

该值存储在数据库中，如下所示：

```
NumberDecimal("1000.55")
```

\*\*NumberDecimal()\*\*构造函数还接受mongo shell中的双精度值（即不带引号），尽管不建议这样做，因为这样做可能会丢失精度。 构造函数创建基于二进制的双精度表示形式的基于十进制的参数（可能会丢失精度），然后将该值转换为精度为15位数字的十进制值。 下面的示例隐式地将值作为双精度值传递，并显示如何以15位精度创建值：

```
NumberDecimal(1000.55)
```

该值存储在数据库中，如下所示：

```
NumberDecimal("1000.55000000000")
```

下面的示例隐式地将该值作为双精度值传递，并说明如何发生精度损失：

```
NumberDecimal(9999999.4999999999)
```

该值存储在数据库中，如下所示：

```
NumberDecimal("9999999.50000000")
```

> **\[success] Note**
>
> **要将十进制数据类型与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 }**                    | **{ “\_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**的双精度表示形式，该表示形式不等于该值的十进制表示形式。\
**NumberDecimal()** 构造函数用于查询以**9.99**十进制表示的文档。 排除双精度类型的值，因为它们与**9.99**的十进制表示形式的确切值不匹配。 查询整数时，将返回所有数字类型的匹配值。 例如，查询10的双精度表示将在结果中包含**10.0**的十进制表示，反之亦然。 **检查十进制类型**

要测试十进制类型，请使用[`$type`](https://docs.mongodb.com/master/reference/operator/query/type/#op._S_type)运算符，其字符串别名为\*\*“decimal”**或**19\*\*（十进制类型的数字代码）。

```
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**类型。

译者：王恒

校对：杨帅


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.mongoing.com/the-mongo-shell/data-types-in-the-mongo-shell.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
