索引的类型
单字段索引
复合索引
其他索引类型
哈希索引:是指按照某个字段的hash值来建立索引,目前主要用于 MongoDB Sharded Cluster 的 Hash 分片,hash索引只能满足字段完全匹配的查询,不能满足范围查询等。
地理位置索引:能很好的解决 O2O 的应用场景,比如『查找附近的美食』、『查找某个区域内的车站』等。
文本索引:能解决快速文本查找的需求,比如有一个博客文章集合,需要根据博客的内容来快速查找,则可以针对博客内容建立文本索引。
索引的操作
测试数据
for (var i = 1; i <= 100; i++) {db.xyj.insert({name: 'taibai' + i,num: i});}
创建匿名索引
查找 num: 100 文档的过程分析
db.xyj.find({num: 100}).explain(true)返回信息:"stage" : "COLLSCAN", 意思为全表扫描"executionTimeMillis" : 144 查询时间
创建匿名索引
1:代表正序, -1:代表 倒序
db.xyj.createIndex({num: 1})返回信息:{"createdCollectionAutomatically": false,"numIndexesBefore": 1, // 添加本次索引之前的索引数"numIndexesAfter": 2, // 添加本次索引之后的索引数"ok": 1}
建立索引后再次查找
db.xyj.find({num: 100}).explain(true)返回信息:"stage" : "IXSCAN", // 通过扫描索引进行查找"indexName" : "num_1", // 如果没有指定索引名称的话, 默认格式为 ‘字段_1’ 或者 ‘字段_-1’"executionTimeMillis" : 0, // 本次执行时间的毫秒数为 0ms
创建命名索引
如果没有指定索引名称的话, 默认格式为 fieldName1 或者 fieldName-1,如果想要自定义索引名称的话,可以在创建的时候指定名称,如下:
db.xyj.createIndex({name: 1}, {name:' myIndexName'})
查询索引
v:表示版本号,key:在那个字段创建了索引,是升序还是降序的,name:索引名称,ns:哪个数据库的集合下
db.xyj.getIndexes()返回信息:[{"v": NumberInt("2"),"key": {"_id": NumberInt("1")},"name": "_id_","ns": "test.xyj"},{"v": NumberInt("2"),"key": {"num": 1},"name": "num_1","ns": "test.xyj"}]
指定需要使用的索引
hint:指定强制使用哪个索引
db.xyj.find({num: "100"}).hint({num:1}).explain(true)
创建复合索引
查询的条件不止一个,需要用复合索引
db.xyj.createIndex({name:1, num:1});
创建 TTL(过期)索引
mongodb 也可以像 redis 一样给文档设置过期数据,建立 ttl 索引,这里设置了10 秒钟的过期时间,10 秒钟之后过期
- 索引字段的值必须 Date 对象,不能是其它类型比如时间戳
- 删除时间不精确,每60秒跑一次,会删除所有过期数据,同时删除也要时间,所以有误差。
db.classTwo.insert({time:new Date()});db.classTwo.createIndex({time: 1}, {expireAfterSeconds: 10});
创建全文索引
测试数据
db.xyj.insertMany([{"name": "Lily", "content": "I am a girl"},{"name": "Tom", "content": "I am a boy"},{"name": "Carl", "content": "I do not know boy girl"}])
创建全文索引
db.xyj.createIndex({content: 'text'})
使用全文索引
最大的问题,全文索引不支持中文。准确的来说,支持中文的能力没有想象中强大。
// 查找包含 ‘girl’ 的文档db.xyj.find({$text: {$search: 'girl'}})// 查找包含 ‘girl’ 或者 ‘boy’ 的文档(多次查找是 与 的关系)db.xyj.find({$text: {$search: 'boy girl'}})// 查找仅包含‘girl’ 不包含‘boy’的文档db.xyj.find({$text: {$search: 'girl -boy'}})// 就是要查找包含 ‘girl boy’ 字符的文档(需要转义)db.xyj.find({$text: {$search: '\"boy girl\"'}})
二维(地理位置)索引
测试数据
db.dili.insertMany([{"gis": [ 1, 1 ]},{"gis": [ 1, 2 ]},{"gis": [ 1, 3 ]},{"gis": [ 2, 1 ]},{"gis": [ 2, 2 ]},{"gis": [ 2, 3 ]},{"gis": [ 3, 1 ]},{"gis": [ 3, 2 ]},{"gis": [ 3, 3 ]}]);
创建二维索引
db.dili.createIndex({gis:'2d'})
使用二维索引
// 查询距离`[1,1]`最近的四个点db.dili.find({gis:{$near: [1,1]}}).limit(4)// 查询以点`[1,2]`和点`[3,3]`为对角线的正方形中的所有的点db.dili.find({gis: {$within: {$box: [[1,2], [3,3]]}}})// 查出以`[2,2]`为圆心,以`1`为半径为规则下圆心面积中的点db.dili.find({gis: {$within: {$center: [[2,2], 1]}}})
删除索引
db.集合名称.dropIndex(索引名称或者创建时的条件)
// 按名称删除db.xyj.dropIndex("age_1")// 按创建条件删除db.xyj.dropIndex({age:1})// 删除所有索引,自带的这个 id 的索引是不会删除的db.xyj.dropIndexes()
