为什么要有索引

查问快! 查问快! 查问快!

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将疏忽这个选项。