mongodb固定集合和自动递增序列的介绍和使用

在上一个mongodb教程中,我们介绍了 RockMongo管理工具和GridFS分布式文件储存系统,在本节中我们会讨论mongodb中的固定集合(capped collection)和自动递增序列的介绍和使用。
一、固定集合(capped collection)固定集合是固定大小的循环集合,它遵循插入顺序,支持创建、读取和删除操作的高性能。通过循环,它意味着当分配给集合的固定大小耗尽时,它将开始删除集合中最旧的文档,而不提供任何显式命令。
如果更新导致文档大小增加,则有上限的集合限制对文档的更新。由于capped集合按磁盘存储的顺序存储文档,因此它确保文档大小不会增加磁盘上分配的大小。有上限的集合最适合存储日志信息、缓存数据或任何其他大容量数据。
1、创建固定集合
为了创建一个有上限的集合,我们使用普通的createCollection命令,但是将capped选项设置为true并以字节为单位指定集合的最大大小。

>db.createCollection("cappedLogCollection",{capped:true,size:10000})

【mongodb固定集合和自动递增序列的介绍和使用】除了集合大小之外,我们还可以使用max参数限制集合中的文档数量:
>db.createCollection("cappedLogCollection",{capped:true,size:10000,max:1000})

如果你想检查一个集合是否有上限,可以使用下面的isCapped命令:
>db.cappedLogCollection.isCapped()

如果你计划将现有的集合转换为capped,则可以使用以下代码来完成:
>db.runCommand({"convertToCapped":"posts",size:10000})

这段代码将把我们现有posts集合转换成一个有上限的集合。
2、查询固定集
默认情况下,对于有上限的集合的find查询将按插入顺序显示结果。但是,如果希望以相反的顺序检索文档,可以使用sort命令,如下面的代码所示:
>db.cappedLogCollection.find().sort({$natural:-1})

关于有上限的集合,还有一些其他的要点值得了解
  • 我们不能从一个有上限的集合中删除文档。
  • 在一个有上限的集合中没有默认索引,甚至在_id字段中也没有。
  • 在插入新文档时,MongoDB实际上不必在磁盘上寻找容纳新文档的位置。它可以盲目地将新文档插入集合的末尾,这使得在上限集合中的插入操作非常快。
  • 类似地,在读取文档时,MongoDB以与磁盘上相同的顺序返回文档,这使得读取操作非常快。
二、自动递增序列MongoDB不像SQL数据库那样具有开箱即用的自动增量功能,默认情况下它使用_id字段的12字节ObjectId作为唯一标识文档的主键,不过在某些情况下,我们可能希望_id字段具有一些除ObjectId之外的自动递增值。
自动递增序列通过使用计数器集合和JS函数的方式实现这一功能。
1、使用计数器集合
考虑以下产品文档,我们希望_id字段是一个自动递增的整数序列,从1、2、3、4一直到n。
{ "_id":1, "product_name": "Samsung", "category": "IT" }

为此创建一个计数器集合,它将跟踪所有序列字段的最后一个序列值。
>db.createCollection("counters")

现在我们将在以pid为键的计数器集合中插入以下文档:
{ "_id":"pid", "sequence_value": 0 }

字段sequence_value跟踪序列的最后一个值,使用以下代码将这个序列文档插入到计数器集合中:
>db.counters.insert({_id:"pid",sequence_value:0})

2、创建Javascript函数
现在我们将创建一个函数getNextSequenceValue,它将以序列名称作为输入,将序列号增加1并返回更新后的序列号。在我们的例子中,序列名是pid:
>function getNextSequenceValue(sequenceName){var sequenceDocument = db.counters.findAndModify({ query:{_id: sequenceName }, update: {$inc:{sequence_value:1}}, new:true }); return sequenceDocument.sequence_value; }

3、使用Javascript函数
我们将在创建新文档并将返回的序列值赋值给文档的_id字段时使用函数getNextSequenceValue。
使用以下代码插入两个示例文档:
>db.products.insert({ "_id":getNextSequenceValue("pid"), "product_name":"A", "category":"IT" }) >db.products.insert({ "_id":getNextSequenceValue("pid"), "product_name":"B", "category":"IT" })

可以看到我们使用了getNextSequenceValue函数来设置_id字段的值,为了验证功能是否实现了,让我们使用find命令获取文档:
>db.products.find()

    推荐阅读