大多数情况下,mongoDB中都是普通的集合,这些集合也称为动态集合,可以自动增长以容纳更多的数据。但这并不适合所有的场景。比如需要保存应用程序的某一个时间段日志,对于历史日志需要定期老化。这种情形下,定长集合就派上了用场。本文描述了定长集合的特性以及给出相关演示。
一、定长集合的特性
需要事先创建,创建时指定大小,即大小固定,后续不可以随意改变
新文档被插入到队列末尾
使用循环的方式老化最老的文档,即不支持从定长集合手动删除文档
数据被顺序写入到磁盘上的固定空间
固定集合不能被分片
由于覆盖特性,其应用场景通常可以用于记录日志
二、演示定长集合
//mongoDB版本及运行环境
C:\Users\Think>mongod --version
db version v3.2.9
git version: 22ec9e93b40c85fc7cae7d56e7d6a02fd811088c
OpenSSL version: OpenSSL 1.0.1p-fips 9 Jul 2015
allocator: tcmalloc
modules: none
build environment:
distmod: 2008plus-ssl
distarch: x86_64
target_arch: x86_64
//创建语法:
db.createCollection(<name>, { capped: <boolean>,
autoIndexId: <boolean>,
size: <number>,
max: <number>,
storageEngine: <document>,
validator: <document>,
validationLevel: <string>,
validationAction: <string>,
indexOptionDefaults: <document> } ))
name指定集合的名字
autoIndexId是否自动基于_id列创建索引,缺省情况下创建索引
size指定collection的大小。
max指定collection中的document的个数
C:\Users\Think>mongo
MongoDB shell version: 3.2.9
connecting to: test
//创建一个名为log的定长集合,长度为100000个字节
> db.createCollection( "log", { capped: true, size: 100000 } )
{ "ok" : 1 }
//创建一个名为log1的定长集合,长度为5242880个字节,可容纳的文档数为5
> db.createCollection("log1", { capped : true, size : 5242880, max : 5 } )
{ "ok" : 1 }
> for (var i=1;i<10;i++){
... db.log1.insert({"ename":"usr"+i});
... }
WriteResult({ "nInserted" : 1 })
> db.log1.find()
{ "_id" : ObjectId("57cbb1cadbe9385190a86560"), "ename" : "usr5" }
{ "_id" : ObjectId("57cbb1cadbe9385190a86561"), "ename" : "usr6" }
{ "_id" : ObjectId("57cbb1cadbe9385190a86562"), "ename" : "usr7" }
{ "_id" : ObjectId("57cbb1cadbe9385190a86563"), "ename" : "usr8" }
{ "_id" : ObjectId("57cbb1cadbe9385190a86564"), "ename" : "usr9" }
//从上面的测试可知,usr1到usr4已经被覆盖了
//判断一个集合是否是定长集合
> db.log.isCapped()
true
//查看集合的状态
> db.getCollection('log1').stats()
{
"ns" : "test.log1",
"count" : 5,
"size" : 190,
"avgObjSize" : 38,
"storageSize" : 16384,
"capped" : true, //表示一个定长集合
"max" : 5, //最大文档数为5
"maxSize" : 5242880,//最大长度为5242880
"sleepCount" : 0,
"sleepMS" : 0,
..........
//定长集合的倒序输出
> var list=db.log1.find().sort( { $natural: -1 } ).toArray();
> printjson(list)
[
{
"_id" : ObjectId("57cbb1cadbe9385190a86564"),
"ename" : "usr9"
},
{
"_id" : ObjectId("57cbb1cadbe9385190a86563"),
"ename" : "usr8"
},
{
"_id" : ObjectId("57cbb1cadbe9385190a86562"),
"ename" : "usr7"
},
{
"_id" : ObjectId("57cbb1cadbe9385190a86561"),
"ename" : "usr6"
},
{
"_id" : ObjectId("57cbb1cadbe9385190a86560"),
"ename" : "usr5"
}
]
//普通集合转换为定长集合
> db.users.insert({ename:"robin",age:25,male:"M"})
WriteResult({ "nInserted" : 1 })
> db.users.isCapped()
false
> db.runCommand({"convertToCapped":"users","size":1000})
{ "ok" : 1 }
> db.users.isCapped()
true