MongoDB--特殊的索引

MongoDB–特殊的索引

一:TTL索引

1. 简介

如果想要控制删除集合,就可以使用TTL索引。TTL索引可以支持文档在一定时间之后自动过期删除,目前TTL索引只能在单字段上建立,并且字段类型必须是date类型或者包含有date类型的数组(如果数组中包含多个date类型字段,则取最早时间为过期时间)

2. 机制
  • 当你在集合中某一个字段建立TTL索引后,后台会有一个单线程,通过不断查询(默认60s一次)索引的值来判断document是否有过期

  • 删除文档的动作还依据mongod实例的负载情况,如果负载很高,可能会稍微延后一段时间再删除

  • 在复制集成员中,TTL后台线程只删除primary的过期数据,如果此实例变为secondary角色,则后台线程闲置

3. TTL的使用
3.1 固定集合的TTL
db.createCollection("capped",{"capped":true,"size":100,"max":5})//创建固定集合
var date=new Date()//得到date数据
db.capped.insert([{"_id":1,"date":date},{"_id":2,"date":date},{"_id":3,"date":date}]) //插入集合

db.capped.insert([{"_id":1,"date":new Date()},{"_id":2,"date":new Date()},{"_id":3,"date":new Date()}])

db.capped.ensureIndex({"date":1},{expireAfterSeconds:60 }) //添加TTL索引,时间单位是秒

查看索引:
cqsm>db.capped.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "cqsm.capped"
        },
        {
                "v" : 2,
                "key" : {
                        "date" : 1
                },
                "name" : "date_1",
                "ns" : "cqsm.capped",
                "expireAfterSeconds" : 180
        }
]

到达时间后发现,固定集合中并没有删除文档;得出结论TTL索引对于固定集合无效。
3.2 动态集合的TTL
db.capped.drop()//删除掉集合
db.capped.insert([{"_id":1,"date":date},{"_id":2,"date":date},{"_id":3,"date":date}]) //插入集合
db.capped.ensureIndex({"date":1},{expireAfterSeconds:60 }) //添加TTL索引,时间单位是秒

cqsm>db.capped.find()  //查看集合
{ "_id" : 1, "date" : ISODate("2019-11-27T02:36:51.850Z") }
{ "_id" : 2, "date" : ISODate("2019-11-27T02:36:51.850Z") }
{ "_id" : 3, "date" : ISODate("2019-11-27T02:36:51.850Z") }

到达时间后:文档被删除
cqsm>db.capped.find()
cqsm>
4. 限制条件

有一下集中情况是无法使用TTL索引的

  • TTL索引是单字段索引,混合索引不支持TTL,并且也会忽略expireAfterSeconds属性

  • 在_id 主键上不能建立TTL索引

  • 在capped collection中(固定集合)不能建立TTL索引,因为MongoDB不能从capped collection中删除文档

  • 不能使用createIndex()去更改已经存在的TTL索引的expireAfterSeconds值,如果想更改expireAfterSeconds,可以使用collMod命令,否则你只能删除索引,然后重建

  • 不能在已有索引的字段上再创建TTL索引了,如果你想把非TTL索引改为TTL索引,那就只能删除重建索引了

5. 使用collMod命令修改expireAfterSeconds值
db.runCommand({"collMod":"apped","expireAfterSeconds":300})

二:全文本索引

1. 全文本索引简介

全文本索引是对文本文件中的字段加索引。

使用全文本索引可以快速的进行文本搜索。但是创建全文本的索引的成本高。

  • 任何一个操作频繁的集合上创建全文本索引可能会导致MongDB过载,最好离线的时候创建全文本索引
  • 全文本索引的集合的写入速度很慢
  • 全文本索引会降低分片时候的数据迁移速度
  • 一个集合上最多只能有一个全文本索引,但是全文本索引可以包含多个字段
  • 全文本索引的字段顺序不重要,每个字段被同等对待,但是可以设置权重(索引一旦创建之后就不能改变权重了)

MongoDB 在 2.6 版本以后是默认开启全文检索的,如果你使用之前的版本,你需要使用以下代码来启用全文检索:

>db.adminCommand({setParameter:true,textSearchEnabled:true})
2. 创建全文本索引
2.1 单键全文索引
如下文件:
cqsm>db.mong.find()
{ "_id" : ObjectId("5dde12748ead21d246cc04a6"), "title" : "hello everyone aa is me" }
{ "_id" : 2, "title" : "aa hello everyone is me sdwd" }
{ "_id" : ObjectId("5dda60627a8eb11f45c1599d"), "title" : "ba a aa" }
{ "_id" : ObjectId("5dda60ac7a8eb11f45c159a2"), "eat" : 22 }

针对title字段建立索引
db.mong.ensureIndex({"title":"text"})

使用全局文本索引模糊查询单个关键词
db.mong.find({$text:{$search:"aa"}})//加不加" "都行
返回结果:
cqsm>db.mong.find({"$text":{$search:"aa"}})
{ "_id" : ObjectId("5dda60627a8eb11f45c1599d"), "title" : "ba a aa" }
{ "_id" : ObjectId("5dde12748ad21d246cc04a6"), "title" : "hello everyone aa is me" }
{ "_id" : 2, "title" : "aa hello everyone is me sdwd" }

使用全局文本索引模糊查询多个关键词,满足其中一个就行
db.mong.find({$text:{$search:"aa is"}})

使用全局文本索引模糊查询同时含有多个关键词
db.mong.find({$text:{$search:" \"aa\" \"is\" "}})

不包含某个字段可以使用负号(3.6 版本不可以使用)
db.mong.find({$text:{$search:"-is aa"}})
2.2 复合全文索引
db.articles.ensureIndex({key_1:'text',key_2:'text'})
2.3 全文索引

在不知道文档包含的字段的情况下,可以使用"$**"在文档的所有字符串字段上创建全文本索引,这样也会对内嵌文档和数组上所有的字符串字段建立索引。

db.articles.ensureIndex({"$**":"text"})
2.4 设置权重
db.mong.ensureIndexes({"title":"text","desc":"text"},{"weight":{"title":3,"desc":2}})
2.6 优化全文本搜索

创建一个复合索引,普通索引+全文索引

db.mong.ensureIndexes({"name":1,"title":"text"})

使用前缀和后缀的形式创建复合索引

db.mong.ensureIndexes({"name":1,"title":"text","age":1})

注意:一个集合只能有一个全文索引,前缀索引字段和后缀索引字段都不可以是多键字段。

三:地理空间索引

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

后面的博客详细介绍和学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值