MongoDB——特殊的索引和集合

固定集合

MongoDB中的“普通”集合是动态创建的,而且可以自动增长以容纳更多的数据。MongoDB中还有另一种不同类型的集合,叫做固定集合,固定集合需要事先创建好,而且它的大小是固定的( 如图6-1所示)。说到固定大小的集合,有一个很有趣的问题:向-一个已经满了的固定集合中插入数据会怎么样?答案是,固定集合的行为类似于循环队列。如果已经没有空间了,最老的文档会被删除以释放空间,新插入的文档会占据这块空间。也就是说,当固定集合被占满时,如果再插入新文档,固定集合会自动将最老的文档从集合中删除。

固定集合的访问模式与MongoDB中的大部分集合不同:数据被顺序写入磁盘上的固定空间。因此它们在碟式磁盘(spinning disk)。上的写入速度非常快, 尤其是集合拥有专用磁盘时(这样就不会因为其他集合的一些随机性的写操作而“中断”)。固定集合可以用于记录日志,尽管它们不够灵活。虽然可以在创建时指定集合大小,但无法控制什么时候数据会被覆盖。

创建固定集合

不同于普通集合,固定集合必须在使用之前先显示创建。可以使用createCollection函数:
在这里插入图片描述
创建了一个1024字节,最大文档数为10的固定集合。固定集合创建之后,就不能改变了(如果需要修改固定集合的属性,只能将它删除之后再重建)。因此,在创建大的固定集合之前应该仔细想清楚它的大小。

注意:为固定集合指定文档数量限制时,必须同时指定固定集合的大小。不管先达到哪-一个限制,之后插入的新文档就会把最老的文档挤出集合:固定集合的文档数量不能超过文档数量限制,固定集合的大小也不能超过大小限制。

创建固定集合时还有另一个选项,可以将已有的某个常规集合转换为固定集合,可以使用convertToCapped命令实现。下 面的例子将test集合转换为一个大小为10 000字节的固定集合:

db.runCommand(
	{"converToCapped": "test", "size":1000}
)

自然排序

对固定集合可以进行一种特殊的排序,称为自然排序。自然排序返回结果集中文档的顺序就是文档在磁盘上的顺序,也就是文档的插入顺序:
MongoDB——特殊的索引和集合_第1张图片
MongoDB——特殊的索引和集合_第2张图片

循环游标

循环游标(tailablecursor)是一种特殊的游标,当循环游标的结果集被取光后,游标不会被关闭。循环游标的灵感来自tail -f 命令(循环游标跟这个命令有点儿相似),会尽可能久地持续提取输出结果。由于循环游标在结果集取光之后不会被关闭,因此,当有新文档插入到集合中时,循环游标会继续取到结果。由于普通集合并不维护文档的插入顺序,所以循环游标只能用在固定集合上。

循环游标通常用于当文档被插入到“工作队列”(其实就是个固定集合)时对新插入的文档进行处理。如果超过10分钟没有新的结果,循环游标就会被释放,因此,当游标被关闭时自动重新执行查询是非常重要的。

注意:不能在mongoshell中使用循环游标

没有_id索引的集合

默认情况下,每个集合都有一个“id"索引。但是,如果在调用createCollection创建集合时指定autoIndexId选项为false,创建集合时就不会自动在" id"上创建索引。实践中不建议这么使用,但是对于只有插入操作的集合来说,这确实可以带来速度的稍许提升。

TTL索引

对于固定集合中的内容何时被覆盖,如果需要更加灵活的老化移出系统(ageoutsystem),可以使用TTL索引(time-to-live index,具有生命周期的索引),这种索引允许为每一个文档设置一个超时时间。一个文档到达预设置的老化程度之后就会被删除。这种类型的索引对于缓存问题(比如会话的保存)非常有用。

在createIndex中指定expireAgterSeconds选项就可以创建一个TTL索引:

在这里插入图片描述

这样就在"lastUpdated"字段上建立了一个TTL索引。如果一个文档的"lastUpdated"字段存在并且它的值是日期类型,当服务器时间比文档的"las tUpdated"字段的时间晚expireAfterSeconds秒时,文档就会被删除。

为了防止活跃的会话被删除,可以在会话上有活动发生时将"lastUpdated"字段的值更新为当前时间。只要"lastUpdated"的时间距离当前时间达到10分钟,相应的文档就会被删除。

MongoDB每分钟对TTL索引进行一次清理,所以不应该依赖以秒为单位的时间保证索引的存活状态。可以使用collMod命令修改expireAfterSeconds的值:
db.runCommand({collMod: "someapp.cache", "expireAfterSeconds": 20 * 60})

在一个给定的集合上可以有多个TTL索引。TTL索引不能是复合索引,但是可以像普通索引一样用来优化排序和查询。

地理空间索引

MongoDB支持几种类型的地理空间索引。其中最常用的是2dsphere索引(用于地球表面类型的地图)和2d索引(用于平面地图和时间连续的数据)。

2dsphere允许使用GeoJSON格式(http://www.geojson.org) 指定点、线和多边形。点可以用形如[longitude,latitude] ([ 经度,纬度])的两个元素的数组表示:

{
	"name":"New York City",
	"loc": {
		"type":"Point",
		"coordinates": [50, 2]
	}
}

线可以用一个又点组成的数组来表示:

{
	"name":"Hudson River",
	"loc": {
		"type":"Line",
		"coordinates": [[0,1], [0,2], [1,2]]
	}
}

多边形的标识方式与线一样(都是一个由点组成的数组),但是type不同:

{
	"name":"New England",
	"loc": {
		"type":"Polygon",
		"coordinates": [[0,1], [0,2], [1,2]]
	}
}

loc字段的名字可以是任意的,但是其中的子对象由GeoJSON指定的,不能改变。

在createIndex中使用2dsphere选项就可以创建一个地理空间索引:

db.world.createIndex({"loc":"2dsphere"})

地理空间查询的类型

符合地理空间索引

2d索引

使用GridFS存储文件

你可能感兴趣的:(MongoDB,后端)