MongoDB 将数据记录存储为 BSON 文档。BSON 是 JSON 文档的二进制表示,带有额外的数据类型。关于 BSON 规范,请参见 bsonspec.org。另请参阅 BSON 类型。
文档结构
文档由“字段-值”对组成,具有以下结构:
{ 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 : Long(1250000) }
上述字段具有以下数据类型:
_id具有 ObjectId。name包含一份嵌入式文档,文档包含字段first和last。birth和death保存日期类型的值。contribs持有一个字符串数组。views持有一个 NumberLong 类型的值。
字段名称
字段名称是具有特定限制和要求的字符串。
一般限制
字段名称的一般限制为:
字段名称不能包含
null字符。服务器允许存储包含点 (
.) 和美元符号 ($) 的字段名称。MongodB 5.0 改进了对在字段名称中使用 (
$) 和 (.) 的支持。有一些限制。请参阅字段名称注意事项,了解详情。
独特性要求
字段名称必须满足以下唯一性标准:
每个字段名称在文档中必须是唯一的。 不得存储具有重复字段的文档,因为如果文档具有重复字段,MongoDB CRUD操作可能会出现意外行为。
MongoDB 不支持插入具有重复字段名的文档。虽然一些 BSON 构建者可能支持创建此类文档,但 MongoDB 并不支持它们,即使插入成功或看似成功也是如此。
即使更新成功或看似成功,也不支持更新具有重复字段名称的文档。
示例,通过MongoDB驱动程序插入具有重复字段名称的BSON文档可能会导致驱动程序在插入之前静默删除重复值,或者可能导致插入包含重复字段的无效文档。查询这些文档会导致结果不一致。
从MongoDB6.1 开始,要查看文档是否具有重复的字段名称,请使用validate 命令并将full 字段设立为true 。在任何MongoDB版本中,使用$objectToArray 聚合操作符可查看文档是否具有重复的字段名称。
注意
对于 _id 字段的特定限制,请参阅The _id 字段。
点符号
MongoDB 使用点表示法来访问数组元素和嵌入式文档字段。
数组
要通过数组的零索引位置指定或访问数组元素,请使用点表示法将数组名称与零索引位置连接起来,并用引号将结果括起来:
"<array>.<index>"
例如,假设文档中包含以下给定字段:
{ ... contribs: [ "Turing machine", "Turing test", "Turingery" ], ... }
要指定 contribs 数组中的第三个元素,请使用 "contribs.2"。
有关查询数组的示例,请参阅:
提示
$[]用于更新操作的所有位置操作符,$[<identifier>]用于更新操作的筛选后位置操作符,$用于更新操作的位置操作符,$当数组索引位置未知时的投影操作符查询数组,获取获取带有数组的点符号示例。
嵌入式文档
要指定或访问嵌入式文档的字段,请使用点表示法连接嵌入式文档名称和字段名称,并使用引号将结果括起来:
"<embeddedDocument>.<field>"
例如,假设文档中包含以下给定字段:
{ ... name: { first: "Alan", last: "Turing" }, contact: { phone: { type: "cell", number: "111-222-3333" } }, ... }
要指定
name中的last字段,使用:"name.last"。要指定嵌套
phone文档中的number字段,请使用:"contact.phone.number"。
警告
分区字段不能使用包含点 (.) 的字段名称。
有关查询嵌入式文档的示例,请参阅:
文档限制
MongoDB 文档具有某些属性,例如文档大小和字段顺序,这些属性会影响查询行为和应用程序性能。
文档大小限制
BSON文档大小的上限为 16 MB。
最大文档大小有助于确保单个文档不会使用过多的 RAM,或者在传输过程中不会使用过多的带宽。MongoDB 提供 GridFS API 协助存储超过最大大小的文档。有关 GridFS 的更多信息,请参阅 mongofiles 和您的 驱动程序 文档。
文档字段顺序
BSON 文档中的字段是有序的(与 JavaScript 对象不同)。
查询中的字段顺序
对于查询,字段顺序行为如下:
比较文档时,字段顺序很重要。例如:
{a: 1, b: 1}等于{a: 1, b: 1}{a: 1, b: 1}不等于{b: 1, a: 1}
查询引擎可以对字段进行重新排序以提高执行效率。字段重新排序可能会发生在中间和最终查询结果中,并且使用以下投影操作符时可能会发生:
重要
由于某些操作可能会重新排序字段,因此请勿依赖于使用上述投影操作符的查询结果中的特定字段顺序。
写入操作中的字段顺序
对于写入操作,MongoDB 会保留文档字段的顺序,但以下情况除外:
_id字段始终是文档中的第一个字段。包含字段名称
renaming的更新可能会导致文档中的字段重新排序。
字段_id
在MongoDB中,存储在标准集合中的每个文档都需要一个唯一的_id字段作为主键。如果插入的文档省略了 _id字段,则MongoDB驱动程序会自动为 _id字段生成 ObjectId。
这也适用于通过执行 upsert: true 的更新操作插入的文档。
行为和限制:
创建集合时,MongoDB 默认在
_id上创建唯一索引。_id字段始终是文档中的第一个字段。如果服务器接收到的文档没有_id字段,则会将该字段移动到文档的开头。_id子字段名称不能以 ($) 符号开头。_id字段可包含除数组、regex 或未定义外的任何BSON 数据类型。
常见 _id 值选项:
以下是为 _id 字段存储值的常用选项:
使用自然唯一标识符(如果可用)。这样可以节省空间并避免附加索引。
生成一个自动递增的数字。
生成一个 UUID 作为 BSON
BinData类型,以便在集合中高效存储 UUID 并创建_id索引。如果满足以下条件,则
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>, ... }