[数据库] 使用索引(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 ] } ] )
建立一个复合索引, 包含name
和event
, 因为含有数组字段, 因此这也是一个多键索引⬇️
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/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律