建立普通索引:(允许索引字段的值重复)
db.集合.ensureIndex({ 字段名: 1/-1 }) 1表示升序,-1表示降序
db.集合.createIndex({ 字段名: 1/-1 }) 1表示升序,-1表示降序
ps: 查询时(多个字段用到索引)如果使用到排序,排序的顺序应该与建立索引时的排序规则完全一样或者完全相反,如果一个相同另外一个不同,则不使用索引。
查看索引:
db.集合.getIndexes( )
> db.test2000.insert({"name":"hello",age:20})
WriteResult({ "nInserted" : 1 })
> db.test2000.find()
{ "_id" : ObjectId("5ae0232f625b9ddd91a0e7ae"), "name" : "hello", "age" : 20 }
> db.test2000.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test2000.test2000"
}
]
建立索引前
> db.test2000.ensureIndex({name:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.test2000.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test2000.test2000"
},
{
"v" : 2,
"key" : {
"name" : 1
},
"name" : "name_1",
"ns" : "test2000.test2000"
}
]
建立索引后
建立唯一索引:(建立唯一索引后,索引的字段值不能重复)
db.集合.ensureIndex( {字段名: 1}, {unique: true} )
> db.test2000.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test2000.test2000"
},
{
"v" : 2,
"key" : {
"name" : 1
},
"name" : "name_1",
"ns" : "test2000.test2000"
}
]
> db.test2000.insert({name:"hello",age:40})
WriteResult({ "nInserted" : 1 })
> db.test2000.find()
{ "_id" : ObjectId("5ae0232f625b9ddd91a0e7ae"), "name" : "hello", "age" : 20 }
{ "_id" : ObjectId("5ae02421625b9ddd91a0e7af"), "name" : "hello", "age" : 30 }
{ "_id" : ObjectId("5ae02432625b9ddd91a0e7b0"), "name" : "hello", "age" : 40 }
使用普通索引
> db.test2000.createIndex({age:1},{unique:true})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"ok" : 1
}
> db.test2000.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test2000.test2000"
},
{
"v" : 2,
"key" : {
"name" : 1
},
"name" : "name_1",
"ns" : "test2000.test2000"
},
{
"v" : 2,
"unique" : true,
"key" : {
"age" : 1
},
"name" : "age_1",
"ns" : "test2000.test2000"
}
]
> db.test2000.insert({"name":"world",age:20})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test2000.test2000 index: age_1 dup key: { : 20.0 }"
}
})
使用唯一索引
建立复合索引:(以多个字段为唯一标识来建立索引)
db.集合.ensureIndex( {字段1:1, 字段2:1, 字段3:1} )
> db.test2000.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test2000.test2000"
}
]
> db.test2000.createIndex({name:1,age:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.test2000.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test2000.test2000"
},
{
"v" : 2,
"key" : {
"name" : 1,
"age" : 1
},
"name" : "name_1_age_1",
"ns" : "test2000.test2000"
}
]
使用复合索引
(*)将多个键组合在一起,创建索引
(*)前面的例子:db.emp.createIndex({"deptno":1,"sal":-1})
(*)示例:
(1)仅把deptno作为查询条件
db.emp.find({"deptno":10}).explain() ---> 会用的索引:indexName" : "deptno_1_sal_-1",
(2)把deptno和sal作为查询条件
db.emp.find({"deptno":10,"sal":3000}).explain()---> 会用的索引:indexName" : "deptno_1_sal_-1",
(3)把deptno和sal作为查询条件,但是把sal放在前面
db.emp.find({"sal":3000,"deptno":10}).explain()---> 会用的索引:indexName" : "deptno_1_sal_-1",
(4)仅把sal作为查询的条件
db.emp.find({"sal":3000}).explain() ----> 不会用到索引,执行全表扫描
(*)复合索引与排序
db.emp.find().sort({"deptno":1,"sal":-1}).explain() ---> 会用的索引:indexName" : "deptno_1_sal_-1",
db.emp.find().sort({"deptno":-1,"sal":1}).explain() ---> 会用的索引:indexName" : "deptno_1_sal_-1",
db.emp.find().sort({"deptno":1,"sal":1}).explain() ----> 不会用到索引,执行全表扫描
db.emp.find().sort({"deptno":-1,"sal":-1}).explain() ----> 不会用到索引,执行全表扫描
复合索引注意点
建立全文索引:(可以在集合中查询包含关键字的文档)
db.集合名.createIndex({字段名1:text,字段名2:text})
1、全文索引(Text Index)
(*)首先,在对应的collection上创建Text Index
(*)一个collection上,只能创建一个Text Index
(*)但是这个全文索引可以包含多个列值
db.stores.createIndex({"name":"text","description":"text"})
2、执行全文检索($text操作符)
(*)包含coffee、java、shop的文档
db.stores.find({$text:{$search:"java coffee shop"}}) ---> 不区分大小写
执行计划
db.stores.find({$text:{$search:"java coffee shop"}}).explain("executionStats")
(*)包含“coffee shop”的文档
db.stores.find({$text:{$search:"\"coffee shop\""}})
(*)包含java或者shop,但不包含coffee
db.stores.find({$text:{$search:"java shop -coffee"}})
(*)排序:文本检索的相关性---> $meta来计算textScore
db.stores.find(
{$text:{$search:"java coffee shop"}},
{score:{$meta:"textScore"}}
).sort({score:{$meta:"textScore"}})
(*)中文检索
db.stores.find({$text:{$search:"java 蛋糕"}})
使用全文索引
建立过期索引:(索引过期后自动删除,但只对date类型有用)
(*)过期索引存在一个过期的时间,如果时间过期,相应的数据会被自动删除
(*)数据:用户登录的信息,日志
(*)示例
db.testindex3.insert({"_id":1,"name":"Tom"})
db.testindex3.createIndex({"name":1},{expireAfterSeconds:30})
(*)注意:过期索引一定针对是时间的类型
db.testindex4.insert({"_id":1,"currentTime":new Date()})
db.testindex4.createIndex({"currentTime":1},{expireAfterSeconds:30})
过期索引
删除索引:
db.集合.dropIndex( { 字段名:1 } )
建立索引注意点
- 根据需要选择是否需要建立唯一索引
- 索引字段是升序还是降序在单个索引的情况下不影响查询效率,但是带复合索引的条件下会有影响
- 数据量巨大并且数据库的读出操作非常频繁的时候才需要创建索引,如果写入操作非常频繁,创建索引会影响写入速度