[数据库] 使用索引(2): mongoDB

mongoDB的索引

mongodb的索引和mysql基本类似, 也是默认主键(相当于mongo中的_id字段)为索引, 进行索引排序etc.

索引分类

单键索引

将一个字段作为索引, 默认_id, 也可以将其他字段作为索引

db.collection.createIndex({year: 1})
其中value为1则是正序, 为-1则是倒序

复合索引

将多个字段组合作为索引, 最多为32个字段; 对应的查询语句同样遵循最左前缀原则
注意name字段一直在第一个位置

//添加复合索引,name正序,age倒序
db.userinfos.createIndex({"name":1,"age":-1})

//过滤条件为name,或包含name的查询会使用索引(索引的第一个字段)
db.userinfos.find({name:'张三'})
db.userinfos.find({name:"张三",age:23})

//查询条件为age时,不会使用上边创建的索引,而是使用的全表扫描
db.userinfos.find({age:23}).explain()

在mongodb中, 还存在一个ESR规则(Equality, Sort, Range), 这个规则提供了一个推荐的复合索引的key顺序

ESR rule

https://www.mongodb.com/docs/manual/tutorial/equality-sort-range-rule/#std-label-esr-indexing-rule
esr规则的目的是规范索引中key按照相等 -> 排序 -> 范围的顺序, 例如

// a query contains all the elements in ESR rule
db.cars.find(
   {
       manufacturer: 'Ford',
       cost: { $gt: 15000 }
   } ).sort( { model: 1 } )

这时候的索引最好为{ manufacturer: 1, model: 1, cost: 1 }

多键索引

多键索引是为了提高含有数组类型的字段的查询效率
假设doc里存在addr字段, 该字段下是一个数组, 数组内是属性为zip的bson对象

db.<collection>.createIndex( { "addr.zip: 1" } )就是在zip属性上添加索引

复合索引必须含有非数组类型

多键索引可以实现复合索引, 但需要注意的是如果复合索引里的key都是数组类型的话, 是不行的, 必须至少有一个是非数组

如果数组里只含有元素而非对象, 可以以数组为查找条件(猜的

既然能将数组放入索引, 那么数组在某些情况下也可以作为查找条件
首先建立我们的数据集⬇️

db.inventory.insertMany( [
   { _id: 5, type: "food", item: "apple", ratings: [ 5, 8, 9 ] }
   { _id: 6, type: "food", item: "banana", ratings: [ 5, 9 ] }
   { _id: 7, type: "food", item: "chocolate", ratings: [ 9, 5, 8 ] }
   { _id: 8, type: "food", item: "fish", ratings: [ 9, 5 ] }
   { _id: 9, type: "food", item: "grapes", ratings: [ 5, 9, 5 ] }
] )

建立一个复合索引, 包含nameevent, 因为含有数组字段, 因此这也是一个多键索引⬇️

db.matches.createIndex( { name: 1, event: 1 } )

针对name字段的查找可以成功, 但对于name+event的查找会失败
但是mongodb支持直接查找数组, 准确的说是被查找数组的第一个元素

db.inventory.createIndex( { ratings: 1 } )
db.inventory.find( { ratings: [ 5, 9 ] } )

上面语句会先查找所有在ratings里含有5的记录, 不论5的位置在哪里; 下一步则是在上一步返回的数据集里查找等于[5, 9]的记录, 注意这里是等于

索引属性

https://www.mongodb.com/docs/manual/core/indexes/index-properties/

唯一索引

令索引必须唯一
db.members.createIndex( { "user_id": 1 }, { unique: true } )

局部索引

对集合中的部分数据添加索引
db.restaurants.createIndex( { cuisine: 1, name: 1 }, { partialFilterExpression: { rating: { $gt: 5 } } } )

这条语句创建了一个复合索引, 只针对rating值大于5的记录; 当查询得到的数据集是rating > 5集合的子集的时候, 就可以利用索引, 否则就会全文搜索

TTL索引

TTL索引用来定时删除document, 只能在(或包含)date类型的字段(的数组)上

这条语句会让eventLog集合里的document按照lastModifiedDate字段排序, 在lastModifiedDate+3600s后被mongo删除

db.eventlog.createIndex( { "lastModifiedDate": 1 }, { expireAfterSeconds: 3600 } )
更多的看这里 https://www.mongodb.com/docs/manual/core/index-ttl/

posted @ 2024-02-24 14:06  Akira300000  阅读(10)  评论(0编辑  收藏  举报