关于mongodb:你知道MongoDB的10种索引吗

40次阅读

共计 3129 个字符,预计需要花费 8 分钟才能阅读完成。

为什么要有索引

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

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

正文完
 0