MongoDB 提供了丰富的数据类型来支持灵活的数据模型。这些数据类型不仅包括大多数编程语言中常见的基本类型,还有一些专门用于处理特定场景的特殊类型。
MongoDB 的数据类型主要可以分为两大类:基本数据类型 和嵌入式类型/结构。
一、基本数据类型(BSON 类型)
BSON(Binary JSON)是 MongoDB 用来存储文档和进行网络传输的二进制编码格式。它扩展了 JSON 的数据类型,提供了更丰富的支持。
以下是 MongoDB 中一些最重要和最常用的 BSON 数据类型:
-
String(字符串)
- 用于存储 UTF-8 编码的字符串数据。
- 是最常用的数据类型之一。
- 例如:
{"name": "Alice"}
-
Number(数字)
-
MongoDB 默认将数字都当作 64 位浮点数(
double
)来处理。但为了精确控制,它细分为:int32
: 32 位整数。int64
: 64 位整数。double
: 64 位双精度浮点数(默认)。decimal
: 高精度浮点数,适用于需要精确计算的金融数据,避免双精度浮点数带来的舍入误差。例如:{"price": NumberDecimal("99.99")}
-
-
Boolean(布尔值)
- 用于存储
true
或false
。 - 例如:
{"isActive": true}
- 用于存储
-
ObjectId(对象ID)
- 用于创建文档的唯一标识符(
_id
)。如果插入文档时未指定_id
,MongoDB 会自动创建一个ObjectId
作为_id
。 - 它是一个 12 字节的 BSON 类型,包含时间戳、机器标识、进程ID和随机计数器,保证了在分布式环境下的大致有序和唯一性。
- 例如:
{"_id": ObjectId("507f1f77bcf86cd799439011")}
- 用于创建文档的唯一标识符(
-
Date(日期)
- 用于存储 UNIX 时间戳(UTC 时间,从 1970年1月1日 开始的毫秒数)。
- 例如:
{"createdAt": new Date()}
-
Null(空值)
- 用于存储空值或不存在的字段。
- 例如:
{"middleName": null}
-
Binary Data(二进制数据)
- 用于存储二进制数据,如图片、视频、文件等。
- 例如:
{"avatar": BinData(0, "...")}
-
Array(数组)
- 用于将多个值存储在一个键下。数组可以包含不同类型的数据,甚至是嵌套的文档。
- 例如:
{"tags": ["mongodb", "database", "nosql"], "scores": [98, 97, 96]}
-
Timestamp(时间戳)
- 一个特殊的内部时间戳类型,与
Date
不同。它也是 64 位的值。 - 前 32 位是
time_t
值(秒 since UNIX epoch),后 32 位是给定秒内的递增序数。 - 注意 :通常不需要在应用中使用这个类型,
Date
类型更常用。Timestamp
主要用于 MongoDB 内部(如 oplog)。
- 一个特殊的内部时间戳类型,与
-
Regular Expression(正则表达式)
- 用于存储正则表达式,查询时可以直接使用。
- 例如:
{"pattern": /^abc./i}
-
JavaScript(Code)
- 用于存储 JavaScript 代码。
- 例如:
{"myFunction": function() { /* ... */ }}
-
Min Key and Max Key(最小键和最大键)
- 特殊类型,用于比较目的。
MinKey
始终小于所有其他 BSON 元素,MaxKey
始终大于所有其他 BSON 元素。 - 主要用于内部操作,普通开发中极少使用。
- 特殊类型,用于比较目的。
二、嵌入式类型/结构
这些不是独立的 BSON 类型,而是利用上面提到的类型(特别是 Object
和 Array
)构建的复杂数据结构。
-
Embedded Document(嵌入式文档)
-
一个文档可以作为另一个文档中某个字段的值。这是实现数据反规范化、构建复杂关系(一对一、一对多)的核心特性。
-
例如,一个用户文档中可以嵌入一个地址文档:
json
json{ "_id": ObjectId("..."), "name": "Bob", "address": { // 这是一个嵌入式文档 "street": "123 Main St", "city": "Springfield", "zip": "12345" } }
-
-
Array of Documents(文档数组)
-
数组的元素可以是文档,这是实现一对多关系的另一种常见方式。
-
例如,一篇博客文章可以有多个评论:
json
json{ "_id": ObjectId("..."), "title": "My First Post", "comments": [ // 这是一个文档数组 {"author": "Alice", "text": "Great post!"}, {"author": "Bob", "text": "I agree."} ] }
-
总结与对比
数据类型 | 说明 | 示例 |
---|---|---|
String | UTF-8 字符串 | "name": "John" |
Number | 整数或浮点数(包括高精度 Decimal) | "age": 30 , "price": 19.99 |
Boolean | 布尔值 | "isStudent": true |
ObjectId | 文档的唯一标识 | "_id": ObjectId("...") |
Date | 日期和时间 | "createdAt": new Date() |
Null | 空值 | "data": null |
Array | 值的列表或集合 | "hobbies": ["reading", "cycling"] |
Embedded Doc | 嵌套的文档对象 | "address": {"city": "NYC"} |
Binary Data | 二进制数据(如图片) | "file": BinData(0, "...") |
如何查看字段的数据类型?
在 MongoDB Shell 中,你可以使用 typeof
操作符和 $type
操作符来检查字段的类型。
-
在查询中使用
$type
:查找age
字段类型为double
(类型编号为 1)的文档。javascript
luadb.collection.find( { "age": { $type: 1 } } )
或者使用别名:
javascript
luadb.collection.find( { "age": { $type: "double" } } )
-
在聚合管道中使用
$type
:返回字段的类型字符串。javascript
bashdb.collection.aggregate([ { $project: { "fieldName": 1, "fieldType": { $type: "$fieldName" } } } ])
选择正确的数据类型对数据的一致性、查询性能和存储效率都至关重要。建议始终参考官方文档以获取最新和最准确的信息。