优:加快查询速度javascript
劣:增删改会产生额外的开销、占用空间html
tips: 返回集合中一半以上的数据,全表扫描的效率高java
查看索引:db.test.getIndexes()正则表达式
建立索引:db.test.ensureIndex({"username":1},{"background":true,"name":"index_test_name"}) //已有大量数据时可后台执行不阻塞数组
删除索引: db.test.dropIndex({"username":1})app
查看索引大小: db.test.totalIndexSize()函数
索引顺序:性能
1为正序,-1为逆序优化
在复合索引中需注意顺序(id:1, age:-1)ui
索引属性:
惟一性
db.test.ensureIndex({x:1,y:1},{unique:true})
稀疏性
db.test.ensureIndexx({},{sparse:true/false}) 不稀疏(默认): 1. 可插入不存在索引字段的数据,null; 2. 可筛选不存在字段: db.test.find({m:{$exist:ture}}) 稀疏:
explain
获知系统如何处理请求
cursor 返回游标类型(BasicCursor或BtreeCursor) nscanned 被扫描的文档数量 n 返回的文档数 millis 耗时(毫秒) indexBounds 所使用的索引
hint
强制使用某个索引
db.test.find({"age":20}).hint({"name":1,"age":1}) // .hint(name_1_age_1)
profile
设置日志级别,记录慢查询
_id索引
默认生成惟一字段
单键索引
值为一个单一的值
db.test.ensureIndex({x:1})
多键索引
值具备多个记录,如数组、内嵌文档
db.test.insert({x:[1,2,3,4]})
每个索引字段最多包含一个数组
Y: {_id:1, a:[1,2], b:1, category:"A array"} 与 {_id:2, a:1, b:[1,2], category:"B array"} N: {_id:3, a:[1,2], b:[1,2], category:"AB both array"}
查询
//数组查询 数组中包含: db.fruitshop.find({"fruits":"apple"}) 包含多个: db.fruitshop.find({"fruits":{"$all":["apple", "banana"]}}) 精确匹配: db.fruitshop.find({"fruits":["apple","orange","pear"]}) //顺序与数量一致 特定位置元素查询: db.fruitshop.find({"fruits.1":"orange"}) 查询数组长度: db.fruitshop.find({"fruits":{"$size":3}}) //size不能和其余操做符连用,如'$gt'等 返回固定长度: db.fruitshop.find({"fruits":{"$slice":2}}) //前2个 db.fruitshop.find({"fruits":{"$slice":-1}}) //后1个 db.fruitshop.find({"fruits":{"$slice":[3,6]}}) //第4~7个,无数据则返回[] //内嵌文档 彻底匹配: db.staff.find({"name":{"first":"joe","middle":"bush"}}) //顺序与数量一致 键值对查询: db.staff.find({"name.first":"joe","name.middle":"bush"}) //点表示法,在插入时键名不能包含点(约束) 多层内嵌: elemMatch db.blogs.find({"comment":{"$elemMatch":{"author":"joe", "score":{"$gte":3}}}}) //内嵌文档中匹配author和score条件 where db.fruitshop.find({"$where":function(){}}) //性能低,每一个文档转换成一个javascript对象放入函数执行
复合索引
多个条件,从左到右执行
{a:1,b:1,c:1} => {a:1},{a:1,b:1},{a:1,b:1,c:1} db.test.ensureIndex({x:1,y:1})
过时索引
一段时间后过时,删除相应数据(用户的登陆信息、存储的日志)
db.test.ensureIndex({time:1},{expireAfterSeconds:30})
限制
字段类型必须是ISODate或者ISODate数组(数组中最小的时间)
不能是复合索引(不能指定两个过时时间)
删除时间不精确(后台进程60s跑一次)
全文索引
字符串或者字符串数组可搜索
//创建索引 db.test.ensureIndex({title:"text"}) db.test.ensureIndex({key1:"text",key2:"text"}) //对多个字段建立全文索引 db.test.ensureIndex({$**:"text"}) //对全部字段建全文索引 //查找 不须要指定字段名称: db.test.find({"$text":{"$search":"coffee"}}) //每一个数据集合只容许建立一个全文索引(可针对一个、多个、所有字段) 查找多个关键词(空格表明 或 操做): db.test.find({"$text":{"$search":"aa bb cc"}}) 指定不包含词(-表明 非 操做): db.test.find({"$text":{"$search":"aa bb -cc"}}) 与关系操做: db.test.find({"$text":{"$search":"\"aa\" \"bb\" \"cc\""}}) 类似度查询: db.test.find({"$text":{"$search":"aa bb"}},{"score:{"$meta":"textScore"}"}) //score字段得分越高,相关度越高 db.test.find({"$text":{"$search":"aa bb"}},{"score":{"$meta":"textScore"}}).sort({"score":{"$meta":"textScore"}}) //score相关度排序 //限制 每次查询只能指定一个$text 有了$text则hint(强制指定索引)不起做用 中文支持很差(企业版可支持)
地理位置索引
将点的位置存储,能够按位置查找其余点
2D索引
用于存储和查找平面上的点
db.test.ensureIndex({w:"2d"}) //使用经纬度表示 取值范围 经度[-180,180] 纬度[-90,90] db.test.insert({w:[180,90]}) //查询 使用$near查询距离某个点最近的点(默认返回100个) db.test.find({"$near":[x,y]}) db.test.find({w:{"$near":[x,y],"$maxDistance":"z"}}) //限制返回的最远距离 使用$geoWithin查询某个形状内的点 矩形($box:[[x1,y1],[x2,y2]]) db.test.find({w:{"$geoWithin:{"$box":[[0,0],[3,3]]}}"}}) 圆形($center:[[x,y],r]) db.test.find({w:{"$geoWithin":{"$center":[0,0],5}}}) 多边形($polygon:[[x1,y1],[x2,y2],..) db.test.find({w:{"$geoWithin":{"$polygon":[[0,0],[0,1],[2,5],[6,1]]}}}) 使用$geoNear查询,返回最大距离和平均距离等数据
相关扩展:
《地理位置索引的实现原理》
2Dsphere索引
用于存储和查找球面上的点
db.test.ensureIndex({key:"2dsphere"})