MongoDB的索引(一)

太阳11个月前技术文章316


一、TTL索引

1、语法

db.eventlog.createIndex( { "lastModifiedDate": 1 }, { expireAfterSeconds: 3600 } )

2、TTL索引会根据TTL索引字段在一定的时间限制后自动删除过期文档,TTL索引更多的适用于只需要保存有限时间的集合,如机器生成的事件信息、日志、会话信息等。

3、expireAfterSeconds

1)expireAfterSeconds>0

表示TTL索引字段超过expireAfterSeconds值后会自动被删除

2)expireAfterSeconds=0

更多的用在集合存在一个删除字段,如果该文档包括TTL索引字段,就会自动被MongoDB进行删除,如果该字段不高阔该索引字段,则不被删除

4、如何定义过期数据

1)TTL索引字段超过expireAfterSeconds则被认为是过期文档

2)如果该字段为数组,且数组中由多个时间值,过期时间由最早的时间值决定

3)如果TTL索引字段不存在date或者包含date的数组,该文档永远不会过期

4)如果该索引字段不存在,则该文档永远不会删除

5、删除操作

1)由一个后台线程周期性查看TTL索引并删除过期数据(60s),该线程无法保证可以立刻删除过期的数据

2)TTL后台线程仅仅在副本集的主节点上进行删除,备份节点通过复制进行删除

6、TTL索引的限制

1)TTL索引不支持复合索引

2)_id字段不支持TTL索引

3)capped集合不支持创建TTL索引

4)若要改变expireAfterSeconds的值,必须删除重建索引

5)不能在相同的字段创建expireAfterSeconds不同的TTL索引


二、Unique索引

1、语法

db.collection.createIndex( <key and index type specification>, { unique: true } )

2、唯一索引主要是用来保证该索引列所有文档唯一不重复

3、每个集合的_id默认就是一个唯一索引,但是该唯一索引不可删除

4、在唯一索引字段,null具有唯一性,如果该索引字段已经存在一个null值,再次插入null值会冲突报错

> db.aa.find()
{ "_id" : ObjectId("5d2fee977737353186206a73"), "id" : 1 }
{ "_id" : ObjectId("5d2fee987737353186206a74"), "id" : 2 }
{ "_id" : ObjectId("5d2fee9b7737353186206a75"), "id" : 3 }
{ "_id" : ObjectId("5d2feea87737353186206a76") }
>
>
> db.aa.createIndex({id:1},{unique:true})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.aa.insert({})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.aa index: id_1 dup key: { : null }"
}
})


三、Partial索引

1、语法

db.restaurants.createIndex(
   { cuisine: 1, name: 1 },
   { partialFilterExpression: { rating: { $gt: 5 } } }
)

partialFilterExpression可以指定不同的条件来做部分索引,主要类型如下:

    $exists: 是否存在 <=> 稀疏索引
    $gt, $gte, $lt, $lte :指定字段符合运算部分创建索引
    $type:
    $and:

2、部分索引只要在符合partialFilterExpression条件的文档上创建索引,包含不符合部分文档的查询会使用COLLSCAN

1)创建索引如下

> db.restaurants.createIndex(
...    { cuisine: 1 },
...    { partialFilterExpression: { rating: { $gt: 5 } } }
... )

2)会使用索引的查询:

db.restaurants.find( { cuisine: "Italian", rating: { $gte: 8 } } )

3)不会使用索引的查询:

db.restaurants.find( { cuisine: "Italian", rating: { $lt: 8 } } )
db.restaurants.find( { cuisine: "Italian" } )

3、部分索引的一些限制

1)不可以在相同的字段创建两个不同的partialFilterExpression的部分索引

2)不可以同时使用partialFilterExpression和sparse

3)MongoDB3.2版本才开始支持

4)_id字段不支持使用部分索引

5)部分索引不可作为分片键

4、唯一部分索引中,唯一性仅仅对符合partialFilterExpression部分文档满足

1)示例文档

> db.users.find()
{ "_id" : ObjectId("56424f1efa0358a27fa1f99a"), "username" : "david", "age" : 29 }
{ "_id" : ObjectId("56424f37fa0358a27fa1f99b"), "username" : "amanda", "age" : 35 }
{ "_id" : ObjectId("56424fe2fa0358a27fa1f99c"), "username" : "rajiv", "age" : 57 }
> db.users.createIndex(
...    { username: 1 },
...    { unique: true, partialFilterExpression: { age: { $gte: 21 } } }
... )

2)因唯一性冲突,插入报错

db.users.insert( { username: "david", age: 27 } )
db.users.insert( { username: "amanda", age: 25 } )
db.users.insert( { username: "rajiv", age: 32 } )

3)因不满足partialFilterExpression,不需要满足唯一性

db.users.insert( { username: "david", age: 20 } )
db.users.insert( { username: "amanda" } )
db.users.insert( { username: "rajiv", age: null } )


相关文章

 oracle11g打补丁31718723报错Operation not permitted

oracle11g打补丁31718723报错Operation not permitted

oracle11g 在打gi补丁的时候报错如下:原因:参考mos(Doc ID 2668094.1)可知因为Linux/Unix平台上,安装后一些Oracle可执行文件的权限需要修改成root。这是以...

Redis Sentinel与Cluster安装部署(二)

3.2cluster部署1、在对应的机器,下载、解压redis #详见sentinel部署内相关命令 2、创建对应的文件目录   mkdir -p /usr/lcoal/redis5/clust...

CDP实操(7.1.4版本)--RangerAdmin使用负载均衡实现高可用

CDP实操(7.1.4版本)--RangerAdmin使用负载均衡实现高可用

本文主要是通过配置外部负载平衡器,实现 Ranger HA。1、在 Cloudera Manager 中,选择 Ranger,然后选择Actions > Add Role Instances。2...

PG初识

PG数据库是一种典型的C/S模型应用,不同的客户端通过TCP/IP进行连接、每个连接启动一个fork进程(多进程数据库)。一、pg逻辑架构1.1 pg与MySQL异同对比逻辑架构postgresMyS...

MySQL运维实战之备份和恢复(8.8)恢复单表

xtrabackup支持单表恢复。如果一个表使用了独立表空间(innodb_file_per_table=1),就可以单独恢复这个表。1、Prepareprepare时带上参数--export,xtr...

Prometheus+Consul服务自动发现监控

Prometheus+Consul服务自动发现监控

为什么使用consulprometheus作为新一代的监控利器,有很多优点,部署起来也十分方便。部署prometheus后自然会需要使用prometheus去监控物理机或者虚拟机的资源,这里就需要使用...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。