文档
MongoDB 以 BSON 文档的形式存储数据记录。BSON 是 JSON 文档的二进制表示,但它包含比 JSON 更多的数据类型。有关 BSON 规范,请参阅JSON 文档,尽管它包含比 JSON 更多的数据类型。有关 BSON 规范,请参阅bsonspec.org. 参见 BSON 类型。
兼容性
MongoDB 在以下环境中存储记录
MongoDB Atlas: 云中 MongoDB 部署的全托管服务
MongoDB 企业版: 基于订阅的自托管 MongoDB 版本
MongoDB 社区版: 源代码可用的、免费使用和自托管 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"
。
有关查询数组的示例,请参阅
嵌入式文档
使用点表示法指定或访问嵌入式文档的字段,将嵌入式文档名称与点(.
)和字段名称连接起来,并用引号括起来
"<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兆字节。
最大文档大小有助于确保单个文档不会使用过多的RAM,或者在传输过程中使用过多的带宽。为了存储大于最大大小的文档,MongoDB提供了GridFS API。有关更多信息,请参阅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
字段始终是文档中的第一个字段。包含字段名称重命名(
rename
)的更新可能导致文档中字段的重新排序。
_id
字段
在MongoDB中,每个存储在集合中的文档都需要一个唯一的_id字段,该字段作为主键。如果插入的文档省略了_id
字段,MongoDB驱动程序将自动为_id
字段生成一个ObjectId。
这同样适用于使用upsert: true的更新操作插入的文档。
_id
字段具有以下行为和约束:
默认情况下,MongoDB在创建集合时在
_id
字段上创建一个唯一索引。_id
字段始终是文档中的第一个字段。如果服务器接收到一个没有_id
字段首先的文档,则服务器将移动该字段到开头。如果
_id
包含子字段,子字段名称不能以($
)符号开始。字段
_id
可能包含除数组、正则表达式或未定义之外任何 BSON 数据类型 的值。注意
为确保复制的正常运行,请勿在
_id
字段中存储 BSON 正则表达式类型的值。
以下是一些存储 _id
值的常用选项
使用 ObjectId。
如果可用,使用自然唯一标识符。这样可以节省空间并避免额外的索引。
生成一个自动增加的数字。
在应用程序代码中生成一个 UUID。为了更有效地在集合和
_id
索引中存储 UUID 值,将 UUID 存储为 BSONBinData
类型的值。如果二进制子类型值在 0-7 或 128-135 范围内,并且字节数组的长度为:0、1、2、3、4、5、6、7、8、10、12、14、16、20、24 或 32,则
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
字段,并在向 MongoDB 发送插入操作之前生成 ObjectId
。但是,如果客户端发送一个没有 _id
字段的文档,则 mongod
添加 _id
字段并生成 ObjectId
。
文档结构的其他用途
除了定义数据记录外,MongoDB 在整个数据库中使用文档结构,包括但不限于:查询过滤器、更新规范文档 和 索引规范文档。
查询过滤器文档
查询过滤器文档指定了确定哪些记录用于读取、更新和删除操作的查询条件。
您可以使用 <字段>:<值>
表达式来指定相等条件以及 查询运算符 表达式。
{ <field1>: <value1>, <field2>: { <operator>: <value> }, ... }
有关示例,请参阅
更新规范文档
更新规范文档使用 更新运算符 来指定在更新操作中对特定字段进行的数据修改。
{ <operator1>: { <field1>: <value1>, ... }, <operator2>: { <field2>: <value2>, ... }, ... }
有关示例,请参阅 更新规范。
索引规范文档
索引规范文档定义了要索引的字段和索引类型
{ <field1>: <type1>, <field2>: <type2>, ... }
进一步阅读
有关MongoDB文档模型的更多信息,请下载MongoDB应用程序现代化指南。
下载内容包括以下资源
MongoDB数据建模方法演讲
关于从关系数据库管理系统(RDBMS)迁移到MongoDB的最佳实践和注意事项的白皮书
具有其RDBMS等价的参考MongoDB模式
应用程序现代化评分卡