在 MongoDB 中,固定集合(Capped Collection)是一种特殊类型的集合,它有一个固定的大小限制,一旦达到了这个大小限制,新的文档将会覆盖最早的文档。固定集合通常用于保存最新的数据,比如日志文件或者传感器数据。
固定集合(Capped Collection)是 MongoDB 中的一种特殊类型的集合,它具有固定的大小限制。固定集合在某些场景下具有一些优点,但也存在一些限制和缺点。
高性能:固定集合的存储是预先分配的,不会产生碎片,因此读取和写入的性能通常比普通集合更高。
顺序存储:固定集合的文档按照插入的顺序进行存储,可以方便地按照时间顺序查询和分析数据。
自动覆盖旧数据:当固定集合达到大小限制时,新的文档会自动覆盖最早的文档,无需手动删除旧数据。
大小限制:固定集合的大小是固定的,一旦达到了大小限制,新的文档会覆盖最早的文档。这意味着固定集合不适用于需要永久保存所有数据的场景。
无法删除指定文档:固定集合不支持 deleteMany() 和 deleteOne() 方法,只能使用 remove() 方法来删除文档。这意味着无法删除指定的文档,只能删除整个集合。
无法更新文档大小:固定集合的文档可以被更新,但是更新的文档大小不能超过原始文档的大小。如果需要更新的文档大小超过了原始文档的大小,就需要先删除原始文档,再插入新的文档。
由于固定集合存在高性能、顺序存储、自动覆盖旧数据的优点,那么固定集合在以下场景中可以发挥作用。
固定集合非常适合用于存储日志数据。日志通常是按照时间顺序生成的,并且通常只需要保留最新的日志数据。使用固定集合可以确保日志数据的顺序存储,并且当达到大小限制时,新的日志数据会自动覆盖最早的日志数据。
固定集合也适用于存储传感器数据。传感器数据通常是实时生成的,并且只需要保留最新的数据。使用固定集合可以方便地按照时间顺序查询和分析传感器数据,并且当达到大小限制时,新的数据会自动覆盖最早的数据。
固定集合可以用于存储缓存数据。缓存数据通常是临时性的,只需要保留最新的数据。使用固定集合可以高效地存储和更新缓存数据,并且当达到大小限制时,新的数据会自动覆盖最早的数据。
要创建一个固定集合,可以使用 createCollection() 方法,并指定 capped 参数为 true,以及 size 参数来设置集合的大小限制。语法如下:
> db.createCollection("logs", { capped: true, size: 1048576 }) { "ok" : 1 }
上述示例中,我们创建了一个名为 logs 的固定集合,大小限制为 1MB。
还可以通过 max 属性限制文档最大个数,例如:
> db.createCollection("logs", { capped: true, size: 1048576, max:1000 }) { "ok" : 1 }
怎样判断集合是否为固定集合?下面判断 logs 集合是否为固定集合:
> db.logs.isCapped() true
如果需要将已存在的集合转换为固定集合可以使用以下命令:
> db.runCommand({ "convertToCapped":"logs", size: 1048576, max: 1000 }) { "ok" : 1 }
以上代码将已存在的 logs 集合转换为固定集合。
固定集合文档按照插入顺序储存的,默认情况下查询就是按照插入顺序返回的,例如:
# 插入数据到 logs 集合 > db.logs.insertOne({ message:"log1" }); { "acknowledged" : true, "insertedId" : ObjectId("6503e9adf470730f2bc38485") } > db.logs.insertOne({ message:"log2" }); { "acknowledged" : true, "insertedId" : ObjectId("6503e9b0f470730f2bc38486") } > db.logs.insertOne({ message:"log3" }); { "acknowledged" : true, "insertedId" : ObjectId("6503e9b3f470730f2bc38487") } # 查询固定集合 > db.logs.find() { "_id" : ObjectId("6503e9adf470730f2bc38485"), "message" : "log1" } { "_id" : ObjectId("6503e9b0f470730f2bc38486"), "message" : "log2" } { "_id" : ObjectId("6503e9b3f470730f2bc38487"), "message" : "log3" }
也可以使用 $natural 调整返回顺序。例如:
> db.logs.find().sort({$natural:-1}) { "_id" : ObjectId("6503e9b3f470730f2bc38487"), "message" : "log3" } { "_id" : ObjectId("6503e9b0f470730f2bc38486"), "message" : "log2" } { "_id" : ObjectId("6503e9adf470730f2bc38485"), "message" : "log1" }
注意:在 32 位机子上一个 cappped collection(固定集合)的最大值约为 482.5M,64 位上只受系统文件大小的限制。