1、简介
MongoDB提供了多样性的索引支持,索引信息被保存在system.indexes中,且默认总是为_id创建索引,它的索引使用基本和MySQL的关系型数据库一样,其实可以这样说说,索引是凌驾于数据存储系统之上的另外一层系统,所以各种结构迥异的存储都有相同或者相似的索引实现及使用接口并不足为奇。
2、基础索引
在字段age上创建索引,1(升序),-1(降序)
<span style="font-family:SimHei;font-size:14px;">db.user.ensureIndex({age:1}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } > db.user.getIndexes(); [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.user" }, { "v" : 1, "key" : { "age" : 1 }, "name" : "age_1", "ns" : "test.user" } ] > </span>
说明
上列中显示出来了一共有2个索引,其中_id是创建表的时候自动创建的索引,此索引是不能够被删除的。
当系统已有大量数据时,创建索引的过程是个非常耗时的过程,我们可以在后台执行,只需要制定background:true即可。
>db.user.ensureIndex({age:1},{background:true})
3、文档索引
索引可以任何类型的字段,甚至文档。
<span style="font-family:SimHei;font-size:14px;">> db.factories.insert({name:"www",addr:{city:"BJ",state:"BEIJING"}}); WriteResult({ "nInserted" : 1 })</span>
在addr列上创建索引
<span style="font-family:SimHei;font-size:14px;">> db.factories.ensureIndex({addr:1}); { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }</span>
下面的查询将会用到我们刚刚创建的索引
<span style="font-family:SimHei;font-size:14px;">> db.factories.find({addr:{city:"BJ",state:"BEIJING"}}); { "_id" : ObjectId("54a935b579ceadf5fa8e2ec1"), "name" : "www", "addr" : { "city" : "BJ", "state" : "BEIJING" } }</span>
但是下面这个查询不会用到索引,因为查询的顺序跟索引建立的顺序不一样
<span style="font-family:SimHei;font-size:14px;">> db.factories.find({addr:{state:"BEIJING",city:"BJ"}});</span>
4、组合索引
跟其他数据库产品一样,MongoDB也是有组合索引的,下面我门将在addr.ctiy和addr.state上建立组合索引,当创建组合索引时,字段后面的1表示升序,-1表示降序,是用1还是用-1主要跟排序的时候或者指定范围内查询的时候有关的。
<span style="font-family:SimHei;font-size:14px;">> db.factories.ensureIndex({"addr.city":1,"addr.state":1}); { "createdCollectionAutomatically" : false, "numIndexesBefore" : 2, "numIndexesAfter" : 3, "ok" : 1 } > </span>
此时下面查询都用到了这个索引
<span style="font-family:SimHei;font-size:14px;">> db.factories.find({"addr.city":"BJ","addr.state":"BEIJING"}); { "_id" : ObjectId("54a935b579ceadf5fa8e2ec1"), "name" : "www", "addr" : { "city" : "BJ", "state" : "BEIJING" } } > </span>
<span style="font-family:SimHei;font-size:14px;">> db.factories.find({"addr.city":"BJ"}); { "_id" : ObjectId("54a935b579ceadf5fa8e2ec1"), "name" : "www", "addr" : { "city" : "BJ", "state" : "BEIJING" } } > </span>
<span style="font-family:SimHei;font-size:14px;">> db.factories.find().sort({"addr.city":1,"addr.state":1}); { "_id" : ObjectId("54a935b579ceadf5fa8e2ec1"), "name" : "www", "addr" : { "city" : "BJ", "state" : "BEIJING" } } > </span>
<span style="font-family:SimHei;font-size:14px;">> db.factories.find().sort({"addr.city":1}) { "_id" : ObjectId("54a935b579ceadf5fa8e2ec1"), "name" : "www", "addr" : { "city" : "BJ", "state" : "BEIJING" } } > </span>
5、唯一索引
只需要在ensureIndex命令中指定unique:true即可创建唯一索引,比如往表t4中插入两条记录:
<span style="font-family:SimHei;font-size:14px;">> db.t4.insert({firstname:"wang",lastname:"wu"}); WriteResult({ "nInserted" : 1 }) > db.t4.insert({firstname:"wang",lastname:"liu"}); WriteResult({ "nInserted" : 1 }) > </span>
在t4表中建立唯一索引
<span style="font-family:SimHei;font-size:14px;">> db.t4.ensureIndex({firstname:1,lastname:1},{unique:true}); { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }</span>
查看索引:
<span style="font-family:SimHei;font-size:14px;">> db.t4.getIndexes(); [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.t4" }, { "v" : 1, "unique" : true, "key" : { "firstname" : 1, "lastname" : 1 }, "name" : "firstname_1_lastname_1", "ns" : "test.t4" } ]</span>
6、强制使用索引
hint命令可以强制使用某个索引
<span style="font-family:SimHei;font-size:14px;">> db.t5.insert({name:"wangwu",age:20}); WriteResult({ "nInserted" : 1 }) > </span>
创建索引
<span style="font-family:SimHei;font-size:14px;">> db.t5.ensureIndex({name:1,age:1}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }</span>
查询(没有使用索引)
<span style="font-family:SimHei;font-size:14px;">> db.t5.find({age:{$lt:30}}).explain() { "cursor" : "BasicCursor", "isMultiKey" : false, "n" : 1, "nscannedObjects" : 1, "nscanned" : 1, "nscannedObjectsAllPlans" : 1, "nscannedAllPlans" : 1, "scanAndOrder" : false, "indexOnly" : false, "nYields" : 0, "nChunkSkips" : 0, "millis" : 0, "server" : "localhost.localdomain:27017", "filterSet" : false }</span>
强制使用索引
<span style="font-family:SimHei;font-size:14px;">> db.t5.find({age:{$lt:30}}).hint({name:1,age:1}).explain() { "cursor" : "BtreeCursor name_1_age_1", "isMultiKey" : false, "n" : 1, "nscannedObjects" : 1, "nscanned" : 1, "nscannedObjectsAllPlans" : 1, "nscannedAllPlans" : 1, "scanAndOrder" : false, "indexOnly" : false, "nYields" : 0, "nChunkSkips" : 0, "millis" : 37, "indexBounds" : { "name" : [ [ { "$minElement" : 1 }, { "$maxElement" : 1 } ] ], "age" : [ [ { "$minElement" : 1 }, { "$maxElement" : 1 } ] ] }, "server" : "localhost.localdomain:27017", "filterSet" : false }</span>
7、删除索引
删除索引分为删除某张表的所有索引 和删除某张表的某个索引,具体如下:
<span style="font-family:SimHei;font-size:14px;">> db.t5.dropIndexes(); { "nIndexesWas" : 2, "msg" : "non-_id indexes dropped for collection", "ok" : 1 } > </span>
删除t4表中的firstname索引
<span style="font-family:SimHei;font-size:14px;">> db.t4.dropIndex({firstname:1}) { "nIndexesWas" : 2, "ok" : 0, "errmsg" : "can't find index with key:{ firstname: 1.0 }" } > </span>
-----------------------------------MongoDB系列文章更新-----------------------
第二部分 应用篇 第七章 MongoDB MapReduce
第三部分 管理篇 第九章 MongoDB shell之系统命令、用户命令
第三部分 管理篇 第九章 MongoDB shell之eval、进程