文档 (Document)
MongoDB 将数据记录存储为 BSON 文档。BSON 是 JSON 文档的二进制表示形式,但它包含的数据类型比 JSON 多。有关 BSON 规范,请参阅 bsonspec.org。另请参阅 BSON 类型。
兼容性
对于适用于以下环境中托管的部署,MongoDB 会将记录存储为文档:
MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
文档结构
MongoDB 文档由成对的字段和字段值组成,并具有以下结构:
{ field1: value1, field2: value2, field3: value3, ... fieldN: valueN }
字段值可以是任何一种 BSON 数据类型,包括其他文档、数组和文档数组。例如,以下文档包含不同类型的值:
var mydoc = { _id: ObjectId("5099803df3f4948bd2f98391"), name: { first: "Alan", last: "Turing" }, birth: new Date('Jun 23, 1912'), death: new Date('Jun 07, 1954'), contribs: [ "Turing machine", "Turing test", "Turingery" ], views : NumberLong(1250000) }
上述字段具有以下数据类型:
_id
具有 ObjectId。name
包含一份嵌入式文档,文档包含字段first
和last
。birth
和death
保存日期类型的值。contribs
持有一个字符串数组。views
持有一个 NumberLong 类型的值。
字段名称
字段名称为字符串。
文档对字段名称有以下限制:
字段名称
_id
保留用作主键;它的值在集合中必须是唯一的、不可变的,并且可以是除数组或正则表达式之外的任何类型。如果_id
包含子字段,则子字段名称不能以 ($
) 符号开头。
字段名称不能包含
null
字符。服务器允许存储包含点 (
.
) 和美元符号 ($
) 的字段名称。MongodB 5.0 改进了对在字段名称中使用 (
$
) 和 (.
) 的支持。有一些限制。请参阅字段名称注意事项,了解详情。每个字段名称在文档中必须是唯一的。 不得存储具有重复字段的文档,因为如果文档具有重复字段,MongoDB CRUD操作可能会出现意外行为。
MongoDB 查询语言不支持具有重复字段名称的文档。虽然某些 BSON 构建器可能支持创建具有重复字段名称的 BSON 文档,但即使插入成功或看似成功,也不支持将这些文档插入 MongoDB。例如,通过 MongoDB 驱动程序插入具有重复字段名称的 BSON 文档可能会导致驱动程序在插入之前静默删除重复值,或者导致插入包含重复字段的无效文档。对任何此类文档的查询都会导致任意且不一致的结果。
点符号
MongoDB 使用点符号来访问数组的元素和访问嵌入式文档的字段。
数组
要通过从零开始的索引位置指定或访问数组的元素,请用点号 (.
) 将数组名称和从零开始的索引位置连接,并用引号引起来:
"<array>.<index>"
例如,假设文档中包含以下给定字段:
{ ... contribs: [ "Turing machine", "Turing test", "Turingery" ], ... }
要指定 contribs
数组中的第三个元素,使用点符号 "contribs.2"
。
有关查询数组的示例,请参阅:
提示
另请参阅:
$[]
用于更新操作的所有位置操作符,$[<identifier>]
用于更新操作的筛选后位置操作符,$
用于更新操作的位置操作符,$
当数组索引位置未知时的投影操作符查询数组,获取获取带有数组的点符号示例。
嵌入式文档
要使用点符号指定或访问嵌入式文档的字段,请将嵌入式文档名称与点 ( .
) 和字段名称连接起来,并用引号引起来:
"<embedded document>.<field>"
例如,假设文档中包含以下给定字段:
{ ... name: { first: "Alan", last: "Turing" }, contact: { phone: { type: "cell", number: "111-222-3333" } }, ... }
要在
name
字段中指定名为last
的字段,请使用点符号"name.last"
。要在
contact
字段中指定phone
文档中的number
,请使用点符号"contact.phone.number"
。
警告
分区字段不能使用包含点 (.
) 的字段名称。
有关查询嵌入式文档的示例,请参阅:
文档限制
文档具有以下属性:
文档大小限制
BSON 文档的大小限制为 16 MB。
最大文档大小有助于确保单个文档不会使用过多的 RAM,或者传输过程中不会使用过多的带宽。MongoDB 会提供 GridFS API 来存储超过最大大小的文档。有关 GridFS 的详细信息,请参阅 mongofiles
和驱动程序文档。
文档字段顺序
与 JavaScript 对象不同,BSON 文档中的字段为有序字段。
查询中的字段顺序
对于查询,字段顺序行为如下:
比较文档时,字段排序很重要。例如,在查询中将文档与字段
a
和b
进行比较时:{a: 1, b: 1}
等于{a: 1, b: 1}
{a: 1, b: 1}
不等于{b: 1, a: 1}
为了高效执行查询,查询引擎可能会在查询处理过程中对字段重新排序。在其他情况下,当处理这些投影运算符时,可能会对字段重新排序:
$project
、$addFields
、$set
和$unset
。字段重新排序可能发生在中间结果以及通过查询返回的最终结果中。
由于某些操作可能会对字段重新排序,因此对于使用前面列出的投影操作符的查询,您不应依赖于这些查询结果中返回的特定字段排序。
写入操作中的字段顺序
对于写入操作,MongoDB 会保留文档字段的顺序,但以下情况除外:
_id
字段始终是文档中的第一个字段。包含字段名称
renaming
的更新可能会导致文档中的字段重新排序。
字段 _id
在 MongoDB 中,存储在集合中的每个文档都需要一个唯一的 _id 字段作为主键。如果插入的文档省略了 _id
字段,MongoDB 驱动程序会自动为 _id
字段生成一个 ObjectId。
这也适用于通过执行 upsert: true 的更新操作插入的文档。
_id
字段具有以下行为和约束:
默认情况下,MongoDB 在创建集合期间会在
_id
字段上创建唯一索引。_id
字段始终是文档中的第一个字段。如果在服务器收到的文档中,_id
不是第一个字段,则服务器会将该字段移动到开头。如果
_id
包含子字段,则子字段名称不能以 ($
) 符号开头。_id
字段可以包含任何 BSON 数据类型的值(数组、正则表达式或未定义类型除外)。警告
为了确保复制功能正常,请勿在
_id
字段中存储 BSON 正则表达式类型的值。
以下是存储 _id
值的常见选项:
使用自然唯一标识符(如果可用)。这样可以节省空间并避免附加索引。
生成一个自动递增的数字。
在应用程序代码中生成 UUID。为了更有效率地将 UUID 值存储在该集合和
_id
索引中,请将 UUID 存储为 BSONBinData
类型的值。如果满足以下条件,则
BinData
类型的索引键可以更有效地存储在索引中:二进制子类型值的范围是 0-7 或 128-135,并且
字节数组的长度为:0、1、2、3、4、5、6、7、8、10、12、14、16、20、24 或 32。
使用驱动程序的 BSON UUID 工具生成 UUID。请注意,驱动程序实现可能会以不同的方式实施 UUID 序列化和反序列化逻辑,这可能与其他驱动程序不完全兼容。有关 UUID 互操作性的信息,请参阅驱动程序文档。
注意
大多数 MongoDB 驱动程序客户端会包含 _id
字段并生成 ObjectId
,然后再将插入操作发送到 MongoDB。但是,如果客户端发送的文档没有 _id
字段,则 mongod
会添加 _id
字段并生成 ObjectId
。
文档结构的其他用途
除定义数据记录外,MongoDB 还始终使用这种文档结构,包括但不限于:查询筛选条件、更新规范文档和索引规范文档
查询筛选器文档
查询筛选器文档指定条件,确定选择哪些记录进行读取、更新和删除操作。
可以使用 <field>:<value>
表达式指定相等条件和查询运算符表达式。
{ <field1>: <value1>, <field2>: { <operator>: <value> }, ... }
示例请参见:
更新规范文档
更新规范文档使用更新操作符指定在更新操作过程中对特定字段执行的数据修改。
{ <operator1>: { <field1>: <value1>, ... }, <operator2>: { <field2>: <value2>, ... }, ... }
有关示例,请参阅更新规范。
索引规范文档
索引规范文档定义待索引的字段和索引类型:
{ <field1>: <type1>, <field2>: <type2>, ... }
深入阅读
有关 MongoDB 文档模型的更多信息,请下载《MongoDB 应用程序现代化指南》。
下载内容包括以下资源:
介绍使用 MongoDB 进行数据建模的方法
白皮书介绍了从 RDBMS 数据模型迁移到 MongoDB 的最佳实践和注意事项
引用 MongoDB 模式及其 RDBMS 等效模式
应用程序现代化记分卡