你知道MongoDB的10种索引吗?

为何要有索引

查询快! 查询快! 查询快!javascript

MongoDB的10种索引?

建立索引语法:css

db.<collection_name>.createIndex( <key and index type specification><options> )
复制代码

咱们的record Collection存在以下documentjava

{
  "_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查询git

单键索引

db.records.createIndex( { score1 })
复制代码

复合索引

db.records.createIndex( { userId1, score: 1})
复制代码

多值索引

db.records.createIndex( { "addr.zip": 1 })
复制代码

地理空间索引

MongoDB为坐标平面查询提供了专门的索引,称为地理空间索引。这种查询须要两个维度,因此参数是2d。web

db.map.ensureIndex({"gps" : "2d"});
复制代码

gps键的值必须是某种形式的一对值:一个包含2个元素的数组或者是包含2个键的内嵌文档mongodb

{"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位精度。
索引精度不影响查询精度,下降精度的优势是插入操做的处理开销较低,而且占用的空间更少。较高精度的优势是查询扫描索引的较小部分以返回结果。apache

collation(排序规则)容许用户为字符串比较指定特定于语言的规则,例如字母和重音符号的规则。json

地理空间的查询须要$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/manual/core/2dsphere/

它的应用场景能够是 查找附近美食,查找附近停车场等数据。

全文索引

建立索引:

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

相关文章
相关标签/搜索