MongoDB介绍(Documents)
本章介绍以下MongoDB中的document相关概念。
MongoDB将数据记录作为BSON documents来进行存储。BSON是JSON documents的一种二进制表示方式,但是其具有比JSON更多的数据类型(data types)。参看bsonspec.org与BSON Types.
1. Document Structure
MongoDB文档是由field-value对所组成,并且有如下结构:
其中value字段可以是任何的BSON data types,包括其他的documents、arrays以及arrays of documents。例如,下面的document包含多种类型的values:
上面的字段含有如下数据类型:
-
_id
维持着一个ObjectId -
name
维持着一个内嵌的document,该document含有first及last两个字段; -
birth
及death
维持着日期类型的值 -
contribs
维持着字符串数组 -
views
维持着一个NumberLong类型的值
1) FieldNames
字段的名称是字符串类型。
documents的字段名称具有如下限制:
-
字段名称
_id
保留,用作主键(primary key)。其值在整个集合中唯一,并且是不可修改的,可以是除数组之外的任何类型。假如_id
包含子字段(subfields)的话,则子字段的名称不能以$
符号开头 -
字段的名称不能包含
null
字符 -
服务器允许存储的字段名称包含
.
(dot)和美元符号($) -
MongoDB 5.0对字段名称中的
$
及.
符号提供了更高级的支持。同时也有一些限制,请参看Field Name Considerations以了解更多细节。
BSON文档可以有多个字段含有相同的名称。然而大部分MongoDB接口的内部数据结构实现都不支持有相同的字段名称。假如你需要操作含有相同字段名称的documents,请参看driver documentation。
有一些由MongoDB内部进程所创建的documents可能含有相同名称的字段,但是并没有相关的方法可以向用户documents中添加重复的字段。
2) Field Value Limit
从MongoDB 2.6到featureCompatibilityVersion (fCV)被设置为4.0
的版本:针对indexed collections,索引字段的值的长度有Maximum Index Key Length限制。请参看Maximum Index Key Length以了解更多细节。
1.1 Dot Notation
MongoDB使用.
符号来访问数组元素和内嵌的document字段。
1) Arrays
可以通过.
符号来设置或访问下标从0开始的数组元素。具体方式为:
其中<array>
为数组名,<index>
为从0开始的下标。另外注意外层的引号
。
下面的例子中,含有一个字段为contribs的document:
如果要指定contribs
数组的第三个元素,请使用"contribs.2"
。
对于查询数组,请参看:
See Also:
$[]针对更新操作的所有位置操作符
[$[
]](https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/#mongodb-update-up.---identifier--)针对更新操作的过滤的位置操作符 $针对更新操作的位置操作符
$当数组索引位置不确定时的projection操作符
Query An Array点符号访问数组示例
2) Embedded Documents
可以使用.
符号来设置或访问内嵌document的字段。具体方式如下:
注: 外层含有引号
例如,给定含有下面字段的document:
-
要设置
name
字段的last
分量的值时,可以使用"name.last"
-
要设置
contact
字段的电话号码时,可以使用"contact.phone.number"
更多查询内嵌document的示例,请参看:
1.2 Document Limitations
Documents有如下的一些属性:
1) Document Size Limit
BSON document的最大大小为16M字节。最大大小的限制确保了单个document不会占用太多的内存,在进行传输时也不会消耗太多的带宽。要存储超过最大大小的documents,MongoDB提供了GridFs API。参看mongofiles,以及关于GridFs驱动的相关文档
2) Document Field Order
与JavaScript对象不同,BSON中的字段是有顺序的。
2.1) Field Order in Queries
对于查询,字段的顺序行为如下:
-
当进行documents比较时,field的顺序也是有意义的。例如,当比较含有
a
、b
两个字段的document时:- {a: 1, b: 1}等于{a: 1, b: 1}
- {a: 1, b: 1}不等于{b: 1, a: 1}
-
在执行高效的查询时,查询引擎可能会在进行查询处理时对字段进行排序。其他场景下,在执行
$project
、$addFields
、$set
、$unset
这些projection操作符时也可能会对字段进行排序- 查询返回的中间结果或最后结果都有可能对字段进行排序
- 由于有些操作可能对字段进行排序,因此在你使用上面列出的projection操作符时,不应该依赖于查询结果中字段的顺序
2.2) Field Order in Write Operations
对于写操作,MongoDB会保留document字段的顺序,除非遇到如下场景:
-
_id
字段总是作为document的第一个字段 -
包含对字段重命名(rename)的更新操作可能会更改document字段的顺序
2.3) The _id Field
在MongoDB中,存放在collection中的每一个document都有一个唯一的_id
字段作为该document的主键(primary key)。假如一个插入的document省略了_id
字段,则MongoDB会自动的为_id
字段产生一个ObjectId
这同样适用于insert:true
的update操作。
_id
字段具有如下行为和限制:
-
默认情况下,MongoDB会在创建collection时为
_id
字段创建一个唯一索引 -
_id
字段总是作为documents的一个字段。假如服务器收到了一个document,其_id
字段不是第一个字段,那么服务器会自动的将该字段移动为第一个字段 -
假如
_id
字段的值包含子字段,则字段的fieldName不能以$
符号开头。 -
_id
字段的值可以是任何BSON data type,但是不能为array、regex、或undefined
警告:为了确保功复制功能运行正常,不要在_id字段存放BSON正则表达式
如下是存储_id
字段的值时的一些常用选项:
-
使用一个ObjectId
-
假如可行的话,使用一个自然的唯一标识符。这可以节省存储空间,并且可以避免额外的索引。
-
产生一个自增(auto-incrementing)数字
-
通过应用程序代码产生一个UUID。为了更高效的在collection以及
_id
索引中存储UUID的值,将UUID作为一个BSONBinData
类型。
采用BinData
类型作为索引的key在如下的条件下可以获得更高的效率:
- 二进制子类型的值在0~7或128~135范围内
-
字节数组的长度为:0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 或32.
- 使用驱动(driver)所提供的UUID设备来产生UUIDs。需要知道的是,driver所提供的UUID序列化与反序列化可能有不同的实现逻辑,因此可能与其他的driver不完全兼容。参看driver documentation以了解更多UUID互操作性信息。
Note:
大多数MongoDB驱动客户端都会包含_id字段,并在执行插入操作之前产生一个ObjectId。然而,假如客户端发送一个不带_id字段的document,那么MongoDB将会增加一个_id字段,并为其生成一个ObjectId
1.3 Other Uses of the Document Structure
除了用于定义数据记录(data record),MongoDB还全面使用document structure,包括且不限于:query filters, update specifications documents, index specification documents
1) Query Filter Documents
通过指定过滤条件来查询特定的documents以进行读取(read)、update、delete操作。
我们可以使用<field>:<value>
表达式来指定相等条件(equality condition)以及query operator表达式。
其他示例,请参看:
- Query Documents
- Query on Embedded/Nested Documents
- Query an Array
- Query an Array of Embedded Documents
2) Update Specification Documents
使用update operators来更新特定的documents的指定字段。
更多示例,请参看Update specifications
3) Index Specification Documents
Index specification documents用于定义索引的字段(field)以及索引类型:
1.4 Further Reading
关于MongoDB文档模型(document model)的更多信息,请下载 MongoDB Application Modernization Guide
可以从中下载到如下资源:
-
MongoDB数据模型的方法论介绍
-
从RDBMS数据模型迁移到MongoD的最佳实践及考量白皮书(white paper)
-
与RDBMS所对应的MongoDB schema参考
-
Application Modernization scorecard
[参看]: