索引操作
索引:存储引擎级别的概念,建立在集合上,基于B-tree数据结构,能够更快地检索数据的方法,存储特定的字段或字段值,且按一定的顺序排序。
建立索引:消耗计算与存储资源
插入文档:引起索引顺序的重排,默认在_id上建立唯一索引
索引分类
单键索引、复合索引、多键值索引、全文索引、散列索引等
//单键索引
>db.users.createIndex( { age: 1 } ) //1为升序,-1为降序 默认索引名字 age_1
>db.users.createIndex({age:-1},{background:true,name:"ageIndex",partialFilterExpression:{age:{$gt:20}}})
>//background后台创建索引,不影响mongod服务
>//name指定索引名字
>//partialFilterExpression 过滤文档,给其建立索引
>sparse, bool, 只给存在的字段创建索引,不与partialFilterExpression同时使用
>expireAfterSeconds 过期时间 xx秒,字段为日期格式
> db.stu1.find()
{ "_id" : ObjectId("61791890cab76e646e11e7ad"), "name" : "tom", "age" : 23 }
{ "_id" : ObjectId("617bd0f8beb128756dc60543"), "name" : "laufing", "age" : 23, "date" : ISODate("2021-10-29T10:46:16.096Z") }
> db.stu1.createIndex({date:1},{expireAfterSeconds:30}) //必须是日期类型的字段
//过期后,文档数据会删除。
>db.users.find({age:25}).explain()//查看查询过程
//复合索引
>db.users.createIndex({name:1,age:-1})
//多键值索引,即key对应的值为数组,
//无法创建复合的多键值索引,即多个key为数组
//地理索引,平面数据2d格式,球面数据2dsphere
>db.city.insert(
{
loc : { type: "Point", coordinates: [ -73.97, 40.77 ] },
name: "Beijing",
category : "c1"
}
)
>db.city.insert(
{
loc : { type: "Point", coordinates: [ -73.88, 40.78 ] },
name: "Tianjing",
category : "c2"
}
)
>db.city.createIndex( { loc : "2dsphere" } )//在loc字段创建球面索引
>db.city.find({loc:"2dsphere"}).explain()
//全文索引,在所有的字符串中查询
>db.users.createIndex( { name: "text" } )
//散列索引只能用于字段完全匹配的查询,不能用于范围查询
>db.users.createIndex( { _id: "hashed" } )
//稀疏索引
>db.users.createIndex( { "key": 1 }, { sparse: true } )
//唯一索引
>db.users.createIndex( { "key": 1 }, { unique: true } )
//过期索引,索引过期后,对应的数据会删除
//这适合存储一些在一段时间之后会失效的数据,比如用户的登录信息,
//想要用户登录信息2天后失效,需要用户重新登录,或者存储的日志,希望这些日志在一段时间后删除
>db.users.insert({time:new Date()})
>db.users.createIndex( {time: 1 }, { expireAfterSeconds: 5 } )//5s后索引过期,数据删除
查看索引
>db.users.getIndexes() //查看集合的所有索引
//查看数据库下的所有集合的索引
db.getCollectionNames().forEach(function(collection)
{
indexes = db[collection].getIndexes();
print("Indexes for " + collection + ":");
printjson(indexes);
});
//删除索引
>db.users.dropIndex({name:1})//删除特定的索引
>db.users.dropIndexes()//删除所有索引,除了_id
//更改现有索引就是删除、重建
索引策略
看查询使用的字段及其查询使用的频率 如果所有的查询都使用==同一个键==时,创建一个单键索引。 如果所有的查询都使用==多个键==时,创建复合索引。
使用索引可以来排序查询结果,但无索引时则在内存中排序。
//单键索引排序
db.users.createIndex( { age: 1 } )
db.users.find().sort( { age: 1 } )
db.users.find().sort( { age: -1 })
//复合索引排序,就必须按照索引顺序
//索引 { a: 1, b: 1 } 可以支持排序 { a: 1, b: 1 } 但不支持 { b: 1, a: 1 } 排序。
//sort中指定的所有键的排序顺序必须和索引中的对应键的排序顺序 完全相同, 或者 完全相反
如索引 { a: 1, b: 1 }支持排序{a:-1,b:-1}
//复合索引的前缀
>db.users.createIndex( { a:1, b: 1, c: 1, d: 1 } )
//那么,该索引的前缀如下:
{ a: 1 }
{ a: 1, b: 1 }
{ a: 1, b: 1, c: 1 }
如果排序的键符合索引的键或者前缀 ,那么MongoDB可以使用 索引 来排序查询结果。
如下排序也可:
db.users.find({a:4,b:3}).sort( { b: 1, c: 1 } )
>db.users.totalIndexSize()//当前索引占用的磁盘空间,字节