Capped Collections
概述
限制集是固定大小的集合,它们支持基于插入顺序插入和检索文档的高吞吐量操作。限制集以类似于循环缓冲区的方式工作:一旦集合填充其分配的空间,它将通过覆盖集合中最旧的文档来为新文档腾出空间。
行为
插入顺序
限制集合能够保留插入顺序。因此,查询并不需要索引来保证以插入顺序来返回文档。减少了索引的消耗,限制集合可以支持更高的插入吞吐。
最旧文档的自动删除
为了为新文档腾出空间,在不需要脚本或显式删除操作的前提下,限制集合自动删除集合中最旧的文档。
例如,oplog.rs集合存放操作日志的在replica set中,oplog.rs也使用了限制集合。思考下面2个限制集合潜在的用例
1.存储高容量系统生成的日志信息。没有索引的情况下向限制集中插入文档的速度接近于直接在文件系统中写日志的速度。此外,内建的*fisrt-in-first-out*特性在管理存储使用时维护了事件的顺序。
2.在限制集中缓存少量的数据。既然缓存是读远大于写,因此或者确保集合经常驻留在工作集(i.e. in RAM),或者接受一些需要索引的写惩罚。
_id 索引
限制集合有一个 _id 字段并且默认在 _id 字段上创建索引
限制和建议
更新
如果您打算更新限制集中的文档,创建一个索引保证这些更新操作不需要进行集合扫描。
文档大小
如果一个更新或替换操作改变了文档大小,操作将会失败。
文档删除
您不能从一个限制集中删除文档,为了从一个集合中删除所有文档,使用drop() 方法来删除集合然后重新创建限制集。
分片
你不能对限制集分片。
查询效率
用自然顺序检索限制集中大部分最近插入的文档。这类似于跟踪日志文件。
聚合 $out
聚合管道运算符$ out无法将结果写入限制集合。
程序
创建一个限制集
您必须使用db.createCollection()方法显式创建限制集合,该方法是create命令的mongo shell中的帮助器。创建限制集合时,必须指定集合的最大大小(以字节为单位),MongoDB将为集合预分配。限制集合的大小包含少量内部开销的空间。
db.createCollection( "log", { capped: true, size: 100000 } )
如果 size 字段小于或等于4096,该集合将会有4096字节。否则的话,MongoDB将会在给定大小的基础上增加为256的整数倍。
另外,你可以为限制集指定最大文档数据,用 max 字段就像下边的文档:
db.createCollection("log", { capped : true, size : 5242880, max : 5000 } )
size参数始终是必需的,即使指定了最大文档数量。如果集合达到最大大小限制,则到达最大文档数量之前,MongoDB将删除较旧的文档。
查询一个限制集
如果你在限制集上执行一个没有指定排序的 find()方法,MongoDB保证结果的顺序是和插入顺序相同。
用同插入相反的顺序检索文档, find() 连同sort()方法,及$natural 参数设置为 -1 就像下面的例子:
db.cappedCollection.find().sort( { $natural: -1 } )
检查一个集合是否是限制集
用 isCapped() 方法来判定一个集合是否是限制集,如下:
转换为限制集
你可以用命令 convertToCapped 转换一个非限制集成为一个限制集
db.runCommand({"convertToCapped": "mycoll", size: 100000});
size参数指定限制集的大小(以字节为单位)。
警告
这个命令将获得一个全局写锁并将阻塞其他操作,直到它完成为止。
在规定的时间周期之后将自动移除数据
当数据到期时对于另外的灵活性,考虑MongodDB的 TTL 索引,就像在 通过设置TTL使集合中的数据过期 中描述的。
TTL Collections 与限制集不兼容。
Tailable游标
你可以用 tailable cursor 与限制集。同unix中的 tail -f 命令相似, tailable光标 “tails” 一个限制集的结尾。随着新文档被插入到限制集,你能用 tailable光标来继续检索文档。