[TOC] ## 索引 ### 索引限制 1. 读操作的集合建议不使用索引 2. 索引存放内存,所以限制超过内存,超过将删除部门索引 #### 查询失效情况 * 正则表达式及非操作符,如 $nin, $not, 等。 * 算术运算符,如 $mod, 等。 * $where 子句 #### 最大范围 * 集合中索引不能超过64个 * 索引名的长度不能超过128个字符 * 一个复合索引最多可以有31个字段 ### 索引类型 |Parameter| Type| Description| |---|---|---| |background| Boolean| 非阻塞建立索引 默认值为false。| |unique| Boolean| 建立的索引是否唯一。默认值为false.| |name| string| 索引的名称。默认根据规则生成| |expireAfterSeconds| integer| 设定TTL设定,设定文档的生存时间(秒)。| #### expireAfterSeconds 设置过期时间 1. 可指定多少秒后过期 ``` db.log_events.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } ) db.log_events.insert( { "createdAt": new Date(), "logEvent": 2, "logMessage": "Success!" } ) ``` 2. 指定某时间点过期 expireAfterSeconds必须设置为0 ``` db.log_events.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } ) db.log_events.insert( { "expireAt": new Date('July 22, 2013 14:00:00'), "logEvent": 2, "logMessage": "Success!" }) ``` ### 索引解析 ``` db.users.find({gender:"M"},{user_name:1,_id:0}).explain() ``` 结果 ``` { "cursor" : "BtreeCursor gender_1_user_name_1", "isMultiKey" : false, "n" : 1, "nscannedObjects" : 0, "nscanned" : 1, "nscannedObjectsAllPlans" : 0, "nscannedAllPlans" : 1, "scanAndOrder" : false, "indexOnly" : true, "nYields" : 0, "nChunkSkips" : 0, "millis" : 0, "indexBounds" : { "gender" : [ [ "M", "M" ] ], "user_name" : [ [ { "$minElement" : 1 }, { "$maxElement" : 1 } ] ] } } indexOnly 字段为 true ,表示我们使用了索引。 cursor 因为这个查询使用了索引,MongoDB 中索引存储在B树结构中,所以这是也使用了 BtreeCursor 类型的游标。如果没有使用索引,游标的类型是 BasicCursor。这个键还会给出你所使用的索引的名称,你通过这个名称可以查看当前数据库下的system.indexes集合(系统自动创建,由于存储索引信息,这个稍微会提到)来得到索引的详细信息。 n 当前查询返回的文档数量。 nscanned/nscannedObjects 表明当前这次查询一共扫描了集合中多少个文档,我们的目的是,让这个数值和返回文档的数量越接近越好。 millis 当前查询所需时间,毫秒数。 indexBounds 当前查询具体使用的索引。 ``` ### 创建索引 ``` db.users.ensureIndex({"tags":1}) ``` 查看索引是否生效 ``` db.users.find({tags:"cricket"}).explain() ``` 显示 `"cursor" : "BtreeCursor tags_1" `说明生效 #### 索引子文档字段 ``` db.users.ensureIndex({"address.city":1,"address.state":1,"address.pincode":1}) ``` 检查是否生效 ``` db.users.find({"address.city":"Los Angeles"}).explain() ``` ### 使用 hint() 强制使用索引 ``` db.users.find({gender:"M"}}).hint({gender:1,user_name:1}) ``` ## 全文索引 ### 开启全文索引 2.6 版本以后是默认开启全文检索的 如果是之前的版本 ``` >db.adminCommand({setParameter:true,textSearchEnabled:true}) ``` ### 查询全文索引 ``` db.posts.find({$text:{$search:"runoob"}}) ``` ### 删除全文索引 ``` //查询索引名 db.posts.getIndexes() //删除索引名 db.posts.dropIndex("post_text_text") ```