mongoDB 定长集合(capped collection)

大多数情况下,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
时间: 2024-10-26 08:20:57

mongoDB 定长集合(capped collection)的相关文章

详解MongoDB中创建集合与删除集合的操作方法_MongoDB

创建集合:createCollection() 方法 MongoDB db.createCollection(name, options)  是用来创建集合. 语法: 基本的 createCollection() 命令语法如下: db.createCollection(name, options) 在命令中, name 是要创建的集合的名称. Options 是一个文件,用于指定配置的集合 参数 类型 描述 Name String 要创建的集合名称 Options Document (可选)指定

代码-MongoDB 线程长连接问题

问题描述 MongoDB 线程长连接问题 我在使用MongoDB的过程当中,遇到如下问题: 我的MongoDB一直存在4个ESTABLISHED 连接,一直未释放,即使任务已经执行完了. 代码如下,其中Client只会在系统启动的时候初始化一次,当然在系统停止contextDestroyed的时候Client也调用了close: public class ExportServer extends BasicMongoServer { public final static Logger LOG

c++-如何在windows下C++编程实现循环发送定长数据包?

问题描述 如何在windows下C++编程实现循环发送定长数据包? 为了对内部网络进行相关测试,所以要用C++编程实现一个循环发包程序,用QT平台进行开发,要发送的数据包都是同样大小,且大小由用户自行设置,用户设置的大小是整个数据包的大小,包括Ip头等等.所以想请问一下这个要用什么实现?rawsocket可以吗? 解决方案 http://www.cnblogs.com/shenck/p/4075141.html

byte-C#中socket通信需要将数据按包头和定长分割,如何做

问题描述 C#中socket通信需要将数据按包头和定长分割,如何做 包头是0x55,每个数据加上包头为11个byte,但是数据中也可能出现0x55,该如何分割 解决方案 一般的解决方法是两种: 1)定义转义符,对内容中的 0x55 进行转义.如将 0x55 转义成 0x54 01;则 0x54 是 0x54 00:用两个字节表示: 2)定义包头后带数据的长度,再加上包尾,最好再加上一个校验位.这样在接收到一包数据后,先按上述定义进行有效性验证. 解决方案二: 包头后面带上长度信息,按长度去截取啊

请问网站的高宽是采用定长还是采用百分比啊?

问题描述 请问网站的高宽是采用定长还是采用百分比啊? 现在网站的高宽一般有二种办法,一定是定长,一种是百分比,那么一般是采用哪种办法呢? 解决方案 看自己的网站需要吧.如果公司是做html5 app的就采用百分比,如果只有pc端还是用px好点.如果都有,建议写两套 解决方案二: 如果用百分比来限定宽度,排版大量的文字.对于那种2k 4k的显示器来说,是一种灾难.没有人愿意阅读过长的文本 解决方案三: 看具体情况.用的比较多的是960px或者1000px居中. 解决方案四: 这个肯定是要看实际的情

定长内存池之BOOST::pool

内存池可有效降低动态申请内存的次数,减少与内核态的交互,提升系统性能,减少内存碎片,增加内存空间使用率,避免内存泄漏的可能性,这么多的优点,没有理由不在系统中使用该技术. 内存池分类: 1.              不定长内存池.典型的实现有apr_pool.obstack.优点是不需要为不同的数据类型创建不同的内存池,缺点是造成分配出的内存不能回收到池中.这是由于这种方案以session为粒度,以业务处理的层次性为设计基础. 2.             定长内存池.典型的实现有LOKI.B

定长字符串的问题

问题描述 项目目前代码dima,basstringa="123456"b=a'此时b为123456------------想要实现定长字符串自动截取功能例dimaasstringdimbasNewMicrosoft.VisualBasic.Compatibility.VB6.FixedLengthString(5)'定义长度5的字符串a="123456"b.value=a'此时b.value=12345-----但问题是这样做需要大量修改现行代码如上面的方法,需要为

用正则,从指定起始位置,在源字符串之中截取定长字符串

[代码]用正则, 从指定起始位置, 在源字符串之中截取定长字符串(含中文)[第四版] [代码]用正则, 从指定起始位置开始, 在源字符串之中截取一定长度的字符串[第四版] [代码]使用正则表达式, 从指定的起始位置开始, 在源字符串之中截取一定长度的字符串[第四次修正] [代码]使用正则表达式, 从字符串头部开始, 在源字符串之中截取一定字节长度的字符串 [代码]使用正则表达式, 从指定的起始位置开始, 在源字符串之中截取一定长度的字符串 (BTW: 中文编码很复杂也有些不合理的地方 高位是 0

深入SQL Server中定长char(n)与变长varchar(n)的区别详解_MsSql

char(n)是定长格式,格式为char(n)的字段固定占用n个字符宽度,如果实际存放的数据长度超过n将被截取多出部分,如果长度小于n就用空字符填充. varchar(n)是变长格式,这种格式的字段根据实际数据长度分配空间,不浪费对于的空间,但是搜索数据的速度会麻烦一点. 一般地说,只要一个表有一个字段定义为varchar(n)类型,那么其余用char(n)定义的字段实际上也是varchar(n)类型. 如果你的长度本身不长,比如就3-10个字符,那么使用char(n)格式效率比较高,搜索速度快