MongoDB是一种开源文档型数据库,它具有高性能,高可用性,自动扩展性
1. 文档数据库
MongoDB用一个文档来表示一条记录,文档的数据结构由键值对组成。MongoDB文档类似于JSON对象,字段值可能是文档,数组,或文档数组。

使用文档的优点:
文档中字段值的数据类型同大多数编程语言中的 原生数据类型 一致 。 嵌入式文档和数组减少了连接查询的需求 。 动态的文档结构支持多态性 。2. 主要特性
高性能MongoDB支持高性能数据存储。特别地:
支持嵌入式数据模型以减少对数据库系统的 I/O 利用索引实现快速查询,并且嵌入式文档和集合也支持索引 丰富的查询语言MongoDB提供了丰富的查询语言以支持读写操作和聚集操作、文本检索、地理信息查询
高可用性MongoDB的复制能力被称作复制集( replica set ),它提供了自动的故障迁移和数据冗余。一个复制集是一组包含了相同数据的多台 MongoDB服务器,它提供了冗余性和加强了数据的可用性。
横向扩展MongoDB的横向扩展能力是其核心功能的一部分:
分片的数据分布在服务器集群上 。 带标签的分片能够引导数据到指定的分片上 。 支持多存储引擎包括: WiredTiger Storage Engine , MMAPv1 Storage Engine 。此外, MongoDB 提供 可插拔存储引擎 API , 允许第三方开发者为 MongoDB开发存储引擎。
3. 数据库和集合
MongoDB 存储BSON文档,例如数据记录在集 合 中,集 合 在数据库中。

3.1 数据库
在 MongoDB 中数据库持有集 合 。
在 Mongo shell中,选 中 一个数据库使用如下命令: use <db> ,例如:
use myDB
创建数据库如果待操作的数据库不存在,那么在第一次 向 MongoDB 存储数据 时, MongoDB会创建这个数据库。例如,使用如下命令操作一个不存在的数据库。
use myNewDB
db.myNewCollection1.insert( { x: 1 } )
insert() 操作创建了 数据库 myNewDB,若 集合 myNewCollection1也不存在,同样地 集合 myNewCollection1也被创建。
3.2 集 合
MongoDB 在集 合 中存储文档,集 合 类似于关系数据库中的表。
创建一个集 合
如果一个集 合 不存在,使用下面命令时 集合 会被创建:
db.myNewCollection2.insert( { x: 1 } )
db.myNewCollection3.createIndex( { y: 1 } )
insert() 和 createIndex() 在集 合 不存在的情况下会创建集 合 。
显式创建集合MongoDB 提供了 db.createCollection() 方法来显示地创建一个集 合 。可以为创建的集合指定参数,例如设置集合的大小或者文档的验证规则,如果不需要指定这些参数,那么没必要显示地创建一个集 合 。
文档验证 ( 3.2版新特性)
默认情况下,一个集 合 中的文档不必具有相同的结构 ,
一个集中的文档不需要具有 一系列 相同的字段,并且不同文档中字段的数据类型可以不同。
修改文档结构可以更改集 合 中的文档结构,如添加新字段,删除现有字段,或将字段值更改为一种新的类型,更新文档结构
3.3 固定集 合
3.3.1 概述
固定集 合 ,即具有固定大小的集 合 ,它支持基于插入顺序的插入和查询这两种高通量操作。固定大小的集 合 的工作方式类似于循环缓存:一旦一个集 合 被填满,待插入的文档会覆盖掉最先插入的文档。
3.3.2 行为
插入顺序固定集 合 保证了插入顺序,因此对于查询操作而言,不需要索引的支持就可以返回多个按顺序排列的文档。没有索引的开销,固定集 合 支持更高的插入吞吐量。
自动删除最先插入的文档为了给新文档让出存储空间,固定集 合 自动删除最先插入的文档而不需要显示的删除操作。
例如,集合 oplog.rs 中存储了 副本集 操作日志,这里 副本集 使用了固定集 合 。考虑下面对固定集 合 可能的操作:
存储由大容量系统生成的日志信息。在 无 索引的情况下,文档插入固定集合的速度与将日志信息写入文件系统的速度相似。此外,先进先出的特性保证了事件的顺序,同时管理了存储的使用。 在固定集合中缓存少量数据。由于缓存重读而非写,你应确保这个集合总在工作集中( 例如, 内存中)或接受一点点写操作,因为索引需要写操作。_id 字段索引
固定集 合 含有 _id字段,此字段索引是默认的。
3.3.3 限制和建议
更新如果你要更新固定集合中的文档,创建索引以防止全表扫描。
文档大小 ( 3.2版本变更)
如果更新或替换操作改变了文档大小,则操作失败 。
删除文档不能删除固定集合中的文档,可使用 drop() 命令删除整个固定集 合 并新建之。
分片固定集合不允许分片 。
查询效率使用自然排序可高效地检索最新插入的元素。这是(有点)像 追踪一个 日志文件。
聚集操作符 $out不能使用聚集管道操作符 $out 将结果写入固定集合
3.3.4 过程
创建固定集合在 mongo shel 中, 使用 db.createCollection() 方法创建固定集 合 ,创建固定集 合 的时候要指定集 合 的字节大小, MongoDB将会提前为所创建的固定集合分配存储空间。固定集合的字节大小包含了内部使用的空间大小。
db.createCollection( "log", { capped: true, size: 100000 } )
如果字段的字节大小小于等于 4096 字节 ,那么固定集 合 的 字节 大小为 4096 字节 。否则 MongoDB 会将给定值提升为 256 字节的整数倍。
另外,你可以使用 max 字段设置集合中文档的最大数量:
db.createCollection("log", { capped : true, size : 5242880, max : 5000 } )
注意:对 size 的设置是必须的。在集合中的文档数量还未达到最大值而集合的字节大小已经达到最大时, MongoDB 同样会移除最先插入的文档。
查询固定集合如果使用 find() 方法查询固定集合而没有指定排序规则,查询返回结果的排序和文档插入时的排序是一样的。
为了使查询结果的排序与插入时相反,可以使用 sort() 方法并将 $natural 参数设置为 -1:
db.cappedCollection.find().sort( { $natural: -1 } )
检查集合是否为固定集合使用 isCapped() 方法检查集合是否为固定集合:
db.collection.isCapped()
将集合转换为固定集合使用 convertToCapped 命令将一个非固定集合转换为固定集合:
db.runCommand({"convertToCapped": "mycoll", size: 100000});
size 参数设定了固定集合的字节大小 。
警告:这个命令将会获得全局写入锁,它会阻塞其他操作直到此操作完成为止。
在指定的一段时间后自动移除数据对于数据过期的情形,为支持额外的灵活性,可使用 MongoDB 的 TTL 索引。这些索引允许你利用一种特殊的类型使数据过期并从普通集合中移除,这种特殊的类型是基于时间字段值和 TTL值的。
TTL集合与固定集合不兼容。
Tailable 游标
对于固定集合,可以使用 Tailable 游标。 Tailable游标类似于Unix 的 tail -f 命令, Tailable 游标 追 踪固定集合的末端。新文档插入固定集合的同时,可以使用 Tailable游标检索文档。
4. 文档
MongoDB将数据存储为BSON 文档, BSON是一个JSON文档的二进制表示形式,但它所包含的数据类型比JSON多。

4.1 文档结构
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为嵌入式文档类型 ( embedded document ) ,包括 first和last字段 birth和death为 日期 类型 ( Date ) contribs为字符 串 数组类型 ( array of strings ) views为长整型 ( NumberLong ) 字段名称字段的名称是字符串。
对于字段的命名有下面的约束:
_id为保留字段,用做主键,_id的值与其所在的集合中必须唯一,不可更改,可以是除数组以外的任何类型。 字段名称不能以 “$”符开始。 字段名称不能包含 “.”。 字段名称不能包含空字符。BSON 文档允许有相同的字段名称。大多数的 MongoDB接口不支持字段名称重复。如果需要重复的字段名称,请查看 你所使用的 驱动文档。
MongoDB内部处理程序 创建的 文档可能会有 重名的字段 ,但不会向用户文档中添加 重名 字段。
字段值约束对于已经索引的集合来说,索引字段值有最大索引键值长度( Maximum Index Key Length )限制。
4.2 圆点记法
MongoDB使用圆点符号来访问数组中的元素和嵌入式文档字段。
数组MongoDB中数组是基于0索引的。使用圆点连接集合名称和索引位置:
"<array>.<index>"
例如,给定下面的文档
{
...
contribs: [ "Turing machine", "Turing test", "Turingery" ],...
}
为了访问第三个元素,可以这样: contribs.2
嵌入式文档使用圆点连接嵌入式文档名称和文档字段名称:
"<embedded document>.<field>"
例如,给定下面的文档
{
...
name: { first: "Alan", last: "Turing" },
contact: { phone: { type: "cell", number: "111-222-3333" } },
...
}
为了指定 last字段,使用"name.last" 。 为了指定 number字段,使用"contact.phone.number"4.3 文档约束
文档大小约束BSON 文档最大为 16MB。设置单个文档大小的最大值 有助于确保单个文档不会 耗尽系统内存,或者在传输的过程中不会占用太多的带宽。为了能够存储超过最大值的文档, MongoDB提供了GridFS API 。
文档字段顺序除以下情况外, MongoDB保持写入时的字段顺序:
_id字段总是位于文档的首位 。 重命名字段可能会引起字段重新排序 。从 2.6版本开始MongoDB保持写入时的字段顺序,但之前的版本并非如此。
_id字段在 MongoDB中,文档需要_id字段作为主键,如果插入文档时没有指定_id字段,MongoDB会使用 ObjectIds 作为默认的 _id的默认值。例如,向集合中插入一个不包含位于文档开始处的_id字段的文档,MongoDB会将_id添加进来并且其类型为 ObjectIds 。
另外,如果 Mongod接收一个 待 插入的不包含 _id字段的文档,Mongod将会添加一个 ObjectIds 类型的字段。
_id字段有下列行为和约束:
默认地,在创建集合的同时, MongoDB 为 _id字段创建唯一索引。 _id字段总是文档中的第一个字段,如果插入文档的_id字段不是第一个字段,那么MongoDB会将其移动到首位。 _id字段可以是除数组以外的任何BSON 类型。警告:为了保证复制功能,不要在 _id字段存储BSON 正则表达式类型。
下面是 关于 _id字段值 的常见选项 :
使用 ObjectIds 类型。 尽可能使用自然唯一字符,这样可以节省存储空间和避免额外的索引。 生成自增长数值 在你的应用程序中使用 UUID。为了在集合和_id索引中更有效地存储UUID,将UUID存储为BSON BinData 类型。如果满足下面的条件,索引键会更有效被存储。binary subtype 值取值范围为 0-7 或 128-135
字节数组的长度是: 0,1,2,3,4,5,6,7,8,10,12,14,16,20,24或32.
使用你正在用的 MongoDB驱动生成UUID。注意你所用的驱动对于UUID的序列化与反序列化与其他驱动可能不兼容。4.4 文档结构其他用途
除了定义数据记录, MongoDB使用文档结构贯穿始终,包括但不限于:查询过滤器,更新规范文档,索引规范文档。
查询过滤器文档查询过滤器文档指定了检索,更新,删除文档的条件。
可以使用 <field>:<value> 表达式来指定相等条件和查询运算符表达式。
{
<field1>: <value1>,
<field2>: { <operator>: <value> },
...
}
更新规范文档在 db.collection.update()方法执行期间,更新规范文档使用更新运算符指明待修改字段。
{
<operator1>: { <field1>: <value1>, ... },
<operator2>: { <field2>: <value2>, ... },
...
}
索引规范文档索引规范文档定义了要索引的字段和索引类型。
{ <field1>: <type1>, <field2>: <type2>, ... }
5. BSON 类型
BSON是 一种 用来存储文档和 MongoDB执行远程调用的二进制序列化格式。BSON规范位于bsonspec.org。
BSON支持以下数据类型,每种数据类型都有一个相应的数字和字符串别名,可以使用别名和$type操作符基于类型匹配模式检索文档。
Type
Number
Alias
Notes
Double
1
“double”
String
2
“string”
Object
3
“object”
Array
4
“array”
Binary data
5
“binData”