MongoDB支持基于集合文档上任意列创建索引。缺省情况下,所有的文档的_id列上都存在一个索引。基于业务的需要,可以基于一些重要的查询和操作来创建一些额外的索引。这些索引可以是单列,也可是多列(复合索引),多键索引,地理空间索引,文本索引以及哈希索引等。 本文主要描述在基于文档上的单列来创建索引。
一、创建语法
语法:db.collection.createIndex(keys, options)
keys:
一个包含字段和值键值对的文档,指定该键即在该键上创建索引,如{age:1}
创建索引时可以指定索引为升序或者降序,索引键之后的值为1为升序,-1为降序
可以基于多个键创建索引,每一个键上可以指定升序或降序
options
该options为创建索引时的相关选项,该选项为文档类型,以下列出几个常用的选项:
background boolean 可选选项(缺省值false)
是否在后台创建索引(不阻塞数据库活动),其值为布尔型,即true或false
unique boolean 可选选项(缺省值false)
用于指定创建的索引是否唯一,其值为布尔型,即true或false
name string 可选选项
是否指定索引的名字。在未指定的情况下,MongoDB会产生一个由键名+排序构成的索引名
partialFilterExpression document 可选选项
部分过滤表达式,如果指定,索引只引用匹配过滤器表达式的文档。
常用的过滤器包括:
equality expressions (i.e. field: value or using the $eq operator),
$exists: true expression,
$gt, $gte, $lt, $lte expressions,
$type expressions,
$and operator at the top-level only
sparse boolean 可选选项(缺省值false)
指定该索引是否为间隙索引,间隙索引占用更少的磁盘空间
从3.2版本之后,MongoDB支持部分索引,部分索引是间隙索引的超集
如果使用MongoDB,建议优先使用部分索引
expireAfterSeconds integer 可选选项
指定一个值,以秒为单位,即TTL值,用于控制多久MongoDB保留此集合中的文档
该选项适用于TTL索引
storageEngine document 可选选项
允许用户在创建索引时指定每个索引所使用的存储引擎的配置。
该引擎选项的值形式为: { <storage-engine-name>: <options> }
存储引擎配置在创建索引是被验证以及记录到oplog,支持副本集成员使用不同的存储引擎
二、单键(列)索引示意图
如下图所示,基于文档score键(列)创建一个单键索引
三、演示创建单列索引
1、演示环境
> db.version()
3.2.10
> db.example.find({},{"_id":0})
{ "id" : 1, "ename" : "leshami", "blog" : "http://blog.csdn.net/leshami", "name" : "robinson_0612" }
演示集合数据,可以参考:http://blog.csdn.net/leshami/article/details/52672310
//查看任意的一个文档
> db.persons.find().limit(1).pretty()
{
"_id" : ObjectId("5812cbaaa129eed14b46458d"),
"name" : "robinson.cheng",
"age" : 25,
"email" : "robinson.cheng@qq.com",
"score" : {
"c" : 89,
"m" : 96,
"e" : 87
},
"country" : "USA",
"books" : [
"JS",
"C++",
"EXTJS",
"MONGODB"
]
}
//查看当前集合上已经存在的索引
> db.persons.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1 //该集合上只有一个基于_id的缺省索引
},
"name" : "_id_",
"ns" : "test.persons"
}
]
2、创建单键(列)索引
//下面我们基于集合persons上文档age列来创建一个升序索引
> db.persons.createIndex({age:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1, //索引创建前的索引数目为1
"numIndexesAfter" : 2, //索引创建后的索引数目为2
"ok" : 1
}
>
//下面使用explain方法查看索引是否被使用
//有关获取执行计划的方法可查看:http://blog.csdn.net/leshami/article/details/53521990
> db.persons.find({age:25}).explain()
{
"queryPlanner" : {
..............
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN", //此处提示使用索引扫描
"keyPattern" : {
"age" : 1
},
"indexName" : "age_1",//索引名字为age列+排列顺序
"isMultiKey" : false, //是否为多键索引
"isUnique" : false, //是否为唯一索引
"isSparse" : false, //是否为间隙索引
"isPartial" : false, //是否为部分索引
"indexVersion" : 1, //索引的版本
"direction" : "forward",//索引查询的方向
"indexBounds" : {
"age" : [
"[25.0, 25.0]"
.........
"ok" : 1
}
//下面通过$gt过滤,这个也将会使用到索引,此处省略执行计划
> db.persons.find({age:{$gt:25}}).explain()
3、基于内嵌文档列创建单列索引
//MongoDB支持在内嵌文档上列上创建单列索引,创建方法与文档上单列创建方法类似。
//在内嵌文档列上的创建,可以使用"." 方式来创建。即内嵌文档列.成员名的方法。
//在内嵌文档中使用索引进行等值匹配,其字段的顺序应该实现精确配置。
//下面在内嵌文档score.c上创建索引
> db.persons.createIndex({"score.c":1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"ok" : 1
}
//查看score.c值为89的查询的执行计划
> db.persons.find({"score.c":89}).explain()
{
"queryPlanner" : {
.......
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN", //基于索引扫描
"keyPattern" : {
"score.c" : 1
},
"indexName" : "score.c_1", //索引的名字
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"score.c" : [
"[89.0, 89.0]"
............
"ok" : 1
}
4、基于内嵌文档创建索引
//基于内嵌文档创建索引只需要指定内嵌文档键(列)即可
//基于内嵌文档创建索引包含嵌入文档的全部内容,而不是嵌入文档的部分列
> db.persons.createIndex({score:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 3,
"numIndexesAfter" : 4,
"ok" : 1
}
//查看基于内嵌文档查询的执行计划及其统计信息
> db.persons.find({score:{c:89,m:96,e:87}}).explain("executionStats")
{
"queryPlanner" : {
........
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1, //返回一个文档
"executionTimeMillis" : 0,
"totalKeysExamined" : 1, //总共检查的键为1个
"totalDocsExamined" : 1, //总共检查的文档为1个
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 2,
"advanced" : 1,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 1,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 2,
"advanced" : 1,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"score" : 1
},
"indexName" : "score_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"score" : [
"[{ c: 89.0, m: 96.0, e: 87.0 }, { c: 89.0, m: 96.0, e: 87.0 }]"
]
},
"keysExamined" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
..........
"ok" : 1
}
5、查看集合上已经存在的索引
//从下面的查询可知,当前persons集合上存在4个索引
> db.persons.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.persons"
},
{
"v" : 1,
"key" : {
"age" : 1
},
"name" : "age_1",
"ns" : "test.persons"
},
{
"v" : 1,
"key" : {
"score.c" : 1
},
"name" : "score.c_1",
"ns" : "test.persons"
},
{
"v" : 1,
"key" : {
"score" : 1
},
"name" : "score_1",
"ns" : "test.persons"
}
]
时间: 2024-09-21 20:26:21