chapter6 特殊的索引和集合

6.1固定集合

    MongoDB中的"普通"集合是动态创建的,而且可以自动增长以容纳更多的数据。MongoDB中还有另一种不同类型的集合,叫做固定集合,固定集合需要事先创建好,而且它的大小是固定的。


    固定集合的访问模式与MongoDB中的大部分集合不同:数据被顺序写入磁盘上的固定空间。因此它们在蝶式磁盘(spinning disk)上的写入速度非常快,尤其是集合拥有专用磁盘时(这样就不会因为其他集合的一些随机性的写操作而"中断")。

6.1.1 创建固定集合

> db.createCollection("my_collection",{"capped":true,"size":100000});
{ "ok" : 1 }
> db.createCollection("my_collection2",
... {"capped":true,"size":100000,"max":100});
{ "ok" : 1 }

    例如将test集合转换为一个大小为10000字节的固定集合:

> db.runCommand({"convertToCapped":"test","size":10000});

    无法将固定集合转换为非固定集合(只能将其删除)

6.1.2 自然排序

    对固定集合可以进行一种特殊的排序,称为自然排序(natural sort)。固定集合中的文档是按照文档被插入的顺序保存的,自然顺序就是文档的插入顺序。


6.1.3 循环游标

    循环游标(tailable cursor)是一种特殊的游标,当循环游标的结果集被取光后,游标不会被关闭。由于循环游标在结果集取光之后不会被关闭,因此,当有新文档插入到集合中时,循环游标会继续取到结果。由于普通集合并不维护文档的插入顺序,所以循环游标只能用在固定集合上。如果10分钟没有新的结果,循环游标就会被释放,因此,当游标被关闭时自动重新执行查询是非常重要的。

6.1.4 没有_id索引的集合

    如果在调用createCollection创建集合时指定autoIndexId选项为false,创建集合时就不会自动在"_id"上创建索引。"_id"索引必须是唯一索引。"_id"索引必须一次成功!如果创建的"_id"索引不和规范,就只能删除集合再重建了。

6.2 TTL索引

    TTL索引(time-to-live index,具有生命周期的索引),这种索引允许为每一个文档设置一个超时时间。一个文档到达预设置的老化程度之后就会被删除。

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


    当服务器时间比文档的"lastUpdated"字段的时间晚expireAfterSecs秒时,文档就会被删除。


    MongoDB每分钟对TTL索引进行清理。

6.3 全文本索引

    MongoDB有一个特殊类型的索引用于在文档中搜索文本。使用正则表达式搜索大块文本的速度非常慢,而且无法处理语言的理解问题。使用全文本索引可以非常快的进行文本搜索,就如同内置了多种语言分词机制的支持一样。创建任何一种索引的开销都比较大,而创建全文本索引的成本更高。全文本索引也会导致比"普通"索引更为严重的性能问题,因为所有字符串都需要被分解、分词,并且保存到一些地方。

    启动MongoDB时指定--setParameter textSearchEnabled=true选项,或者在运行时执行setParameter命令,都可以启用全文本索引:

> db.amdinCommand({"setParameter":1,"textSearchEnabled":true})

    为了进行文本搜索,首先需要创建一个"text"索引:

> db.hn.ensureIndex({"title":"text"})

    现在,必须通过text命令才能使用这个索引:




    匹配到的文档是按照相关性降序排列的:"Ask HN"位于第一位,然后是两个部分匹配的文档。每个对象前面的"score"字段描述了每个结果与查询的匹配程度。

    全文本索引只会对字符串数据进行索引:其他的数据类型会被忽略,不会包含在索引中。一个集合上最多只能有一个全文本索引,但是全文本索引可以包含多个字段:

> db.blobs.ensureIndex({"title":"text","desc":"text","author":"text"})

    全文本索引的字段顺序不重要:每个字段都被同等对待。可以为每个字段指定不同的权重来控制不同字段的相对重要性:

> db.hn.ensureIndex({"title":"text","desc":"text","author":"text"}, {"weights":{"title":3,"author":2}})

    默认的权重是1,权重的范围可以是1-1000000000.

    索引一经创建,就不能改变字段的权重了。

    可以使用"$**"在文档的所有字符串字段上创建全文本索引:这不仅会对顶级的字符串字段建立索引,也会搜索嵌套文档和数组中的字符串字段:

> db.blobs.ensureIndex({"$**":"text"})

    也可以为"$**"设置权重:

> db.hn.ensureIndex({"whatever":"text"},
... {"weights":{"title":3,"author":1,"$**":2}})

6.3.1 搜索语法

    为了精确查询"ask hn"这个短语,可以用双引号将查询内容括起来:



    这比使用OR的匹配慢一些,因为MongoDB首先要执行一个OR匹配,然后在对结果进行AND匹配。

    可以将查询字符串的一部分指定为字面量匹配,另一部分仍然是普通匹配:

> db.runCommand({text:"hn",search:"\"ask hn\" ipod"})

    这会精确搜索"ask hn"这个短语,也会可选地搜索"ipod"。

    也可以使用"-"字符指定特定的词不要出现在搜索结果中:

>db.runCommand({text:"hn",search:"-startup vc"})

    这样就会返回匹配"vc"但是不包含"startup"这个词的文档。

6.3.2 优化全文本搜索































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值