为什么要有索引
查问快! 查问快! 查问快!
MongoDB的10种索引?
创立索引语法:
db.<collection_name>.createIndex( <key and index type specification>, <options> )
咱们的record Collection存在如下document
{ "_id": ObjectId("570c04a4ad233577f97dc459"), "score": 1034, "userId": 123, "location": { state: "ZH", city: "ChengDu" }, "addr": [ {zip: "10036", detail: "高家村五组"}, {zip: "94231", detail: "王家镇三组701"} ]}
_id索引
mongodb会主动为document中的_id字段加上索引,所以能用_id查问就用_id查问
单键索引
db.records.createIndex( { score: 1 })
复合索引
db.records.createIndex( { userId: 1, score: 1})
多值索引
db.records.createIndex( { "addr.zip": 1 })
天文空间索引
MongoDB为坐标立体查问提供了专门的索引,称为天文空间索引。这种查问须要两个维度,所以参数是2d。
db.map.ensureIndex({"gps" : "2d"});
gps键的值必须是某种模式的一对值:一个蕴含2个元素的数组或者是蕴含2个键的内嵌文档
{"gps" : [0,100]}{"gps" : {"x" : -30 , "y" : 30}}{"gps" : {"latitude" : -180, "longitude" : 180 }}
至于键名能够随便。默认状况下,天文空间索引假如值范畴是-180~180(对经纬度来说很不便),咱们同样能够应用参数来对索引进行定制,比方上面的星图
db.star.trek.ensureIndex({"light-years" : "2d"} , {"min" : -1000, "max" : 1000, bits;10}, {collation: {locale: "simple"}});
下面的bits指定的是索引精度,默认状况下2d index应用的是26位精度,在默认范畴-180~180中,大概等于60cm误差,最大能够设置32位精度。
索引精度不影响查问精度,升高精度的长处是插入操作的解决开销较低,并且占用的空间更少。较高精度的长处是查问扫描索引的较小局部以返回后果。
collation(排序规定)容许用户为字符串比拟指定特定于语言的规定,例如字母和重音符号的规定。
天文空间的查问须要$near,它须要两个目标值的数组作为参数
db.map.find({"gps" : {"$near" : [40,-73]}}).limit(10);
默认查100个文档,如果不须要这么多,就应该设置一个少点的值以节约资源。
还能够应用
db.runCommand({geoNear : "map", near: [40,-73],num : 10})
geoNear的形式会返回每个文档到查问点的间隔。
还能够查问矩形和圆形内所有的点,这个时候就要将原来的$near换成$geoWithin .
对于矩形要应用$box选项,它的参数是2个元素的数组,第一个元素指定了左下角坐标,第二个指定了右上角坐标
db.map.find({"gps" : {"$geoWithin " : {"$box" : [[10,20],[15,30]]}}});
如果要查问圆形,则要应用$center,参数变成了圆心和半径
db.map.find({"gps" : {"$geoWithin " : {"$center" : [[12,25],5]}}});
天文空间查问既能够应用平面几何,也能够应用球面几何,依据应用的查问和索引类型来决定。 2dsphere 索引只能反对球面几何,而 2d索引同时反对立体和球面几何。
然而,在 2dsphere索引上应用球面几何的查问将会更高效和精确。
2dsphere : https://docs.mongodb.com/manu...
它的利用场景能够是 查找左近美食,查找左近停车场等数据。
全文索引
创立索引:
db.<collection_name>.createIndex({<key>: "text"});
查问数据:
db.<collection_name>.find( { $text: { $search: "green" } } );
查问以及排序:
db.<collection_name>.find({ "$text": { "$search": "green" }},{ "textScore": { "$meta": "textScore" }}).sort({ "textScore": { "$meta": "textScore" }})
留神这里的textScore并不是汇合中的某个字段,而是mongodb依据搜寻后果计算该条数据的分数(匹配度预报,值越大)
TTL索引
我在之前的文章讲到过这个索引,它实际上是一个具备生命周期的索引,这种索引容许为每一个文档设置一个超时工夫。一个文档达到预设置的老化水平后就会被删除。
db.user_session.createIndex({"updated":1},{expireAfterSeconds:60*60*24});
如果一个文档的updated字段存在并且它的值是日期类型,当服务器工夫比文档的updated字段的工夫晚expireAfterSeconds秒时,文档就会被删除
db.getCollection('user_session').insert( { _id: NumberInt(1), "updated":new Date(), username:'lisi' });
局部索引
db.<collection_name>.createIndex({'wechat': 1 },{ "partialFilterExpression": { "wechat": { "$exists": true } }})
下面的索引示意对存在wechat字段的文档进行索引。局部索引仅索引汇合中合乎指定过滤器表达式的文档,升高了索引创立和保护的性能老本。
局部索引提供了稠密索引性能的超集,应优先于稠密索引应用
稠密索引
db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )
索引不索引不蕴含xmpp_id字段的文档。
哈希索引
db.collection.createIndex( { _id: "hashed" })
哈希索引指依照某个字段的hash值来建设索引,目前次要用于MongoDB Sharded Cluster的Hash分片,hash索引只能满足字段齐全匹配的查问,不能满足范畴查问
后盾形式创立索引
db.<collection_name>.createIndex( <key and index type specification>, {background: true})
建设索引即耗时也费劲,还须要耗费很多资源。应用{background: true}选项能够使这个过程在后盾实现,同时失常解决申请。要是不包含这个选项,数据库会阻塞建设索引期间的所有申请。
阻塞的做法会让索引建设得更快,同时也意味着利用在此期间不能应答。即使后盾进行也会对失常操作有些影响,所以最好选在无关紧要的时刻。后盾创立索引也会减少负载,好在不会让服务器宕机。
不过从4.2版本开始,所有索引构建都应用优化的构建过程,该过程仅在构建过程的开始和完结时才持有排他锁。其余的构建过程将产生交织的读写操作。如果指定该属性,MongoDB将疏忽这个选项。