MongoDB的10种索引,你了解的有几个?

为什么要有索引??

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

MongoDB的10种索引,你了解的有几个?

MongoDBo = I 3的10种O 1 8 N _ 4 t J r索引?

创建索引语法:

db.<collection_name>.createIndex( <key and index type spex u h Rcification>, <options>&nbs$ 6 :p;)

我们的record Collect ( U wion存在如下document

{
  \"A j N ! :_id\": ObjectId(\"570c04a4ad233577f97dc459\"),
  \"score\": 1034,
  \_ d r B h y O m"userId\":w N E T 123,
  \"location\": { state: \"ZH\", city:R 9 } 8 0 \"ChengDu\" },
  \"addr\": [
    {zip: \"10036\", detail: M n / x 9 7;\"高家村五组\"},
    {zip:&z T 2 vnbsp;$ q ~ | ]\"94231\", detail: \"王家镇三组701\"}
  ]
}

_id索引

mongodb会自动为document中的_id字段加上索引,所以能用_id查询就用_id查询

单键索引

db.records.createIndex( {` = I / s score: 1 })

复合索引

db.records.createIndex( { userId: 1,&& 6 onbsp;score: 1})

多值索引

db.records.createIndex( { \"addr.zip\": 1 })

地理空间索引

MongoDB为坐标平面查询提供了专门的索引,称为地理空间索引。这种查询a Q需要两个维度,所以参数k 1 X o P J 0是2d。

db- q w L ` p N G r.map.ensureIndex({\"gps\" :w w w 1 b { L Y \"2d\"});

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

{\"gps\k * v . 3 D" : 2 y c;[0,100]}
{\"gps\4 Z | g f % n b" : {\"x\" : -30 , \"y\" : 30}}
{\"gps\" :&n0 X ! a =bsp! | Y x;{\"latitude\" : -180, \"longitude\" : 180 }}

至于键名可以随意。默认情况下,f = + v ] { ( q地理空间索引假设值范围是-180~180(对经纬度来说很方便),我们同样可以使用参数来对索} 3 g - l 8 a h引进行定制,比如下面的星图

db.star.trek.ensureIndex({\"light-8 o Myears\" : \"2d[ : $ O 1 S z 1 r\"} , {\"min\" : -1000, \"max\" : * R I 3 / H g 2 71000, bits;10}, {collation: {locale: \"simple\"}});t : %

上面的bits指定的是索引精度,默认情况下2d index使用的是26位精度,在默认范围-180~180中,大约等于60cm误差,最大可以设S 3 @ i置32位精度。索引精度不影响查询精度,降低精度的优点是插入操作的处理开销较低,并且占用的空间更少。较高精度的优点是查Z G F k询扫描D v g [ L 0索引的较小部分以返回结果。

collation(排序规n : l ? + m则)允许用户为字符串比较指定特定于语言的规则,例如字母和重音符号的规则。

地理空间的查询需要$near,它需要两个目标值的数组作为参数

db.map.find({\"gps\" : {\"$near\" : [40,-73]}}).limit(10);D @ d ? [ % )

默认查100个文档,如果不D B O V /需要这么多,就应该设置一个少点的值^ ! C a以节约资源。

还可以使用

db.runComma( %  vnd({geoNear : \"map\", near: [40,-73],num :r { A e k R X 10})

geL _ : - G W ooNear的方式E 0 0 J N会返回每个文档到查f 0 k Q询点的距离。7 h V $ w D

还可以查询矩形和圆形内所有的点,这个时候就要将原来的9 O v : f g O z$near换成$gP f z a ?eoWithiH P en .对于矩形要使用$box选项,它的参数是2个元素的数组,第一w 6 W w s个元素指定了左下角坐标,第二个指定了右上角坐标

db.map.find({\"gps\"&nbsA : d T i ` v Y yp;: {\"$geoWithin \" : {\"$box\q $ o" : [[1w f U [0,20],[15,30]]` = . L 9 A}}});6 + Q R @

如果要查询圆形,则要使用$center,参数变成了圆心和半径

db.map.find({\"gps\" : {\"$geoWithin? H i ~ v e h 7 \" : {\"$cenl ] ] ? ^ m K t ter\" : [[12,25],5]}}});

地理K q d / L L空间查询p ] h既可以使用平面几何,也可以使用球面几何,根据使用的查询和索引类型 ! 4 ) t T 3 X来决定。 2dsphere 索引只能支持球面几何,而 2d索引同时支持平面和球面几6 : j 7 ] D何。然而,在 2dsphere索引上使A I 用球面几何的查询将会更高j _ 8 2 I t [效和准确。

2dsphere :r J K E f E https://docs.mongodb.com/manual/coreL h c r * g K r/2dsphere/

它的应用场景可以是 查找附近a | n p y h 3 :美食,查; g @ }找附近停车场等数据。

全文索引

创建索引:

db.<cW d e F @ h xollection_name>.createIndex({<ke8 U V _ ^ A Fy>: \"h  3 I W ( f *text\"});

查询数据:

db.<collection_name>.find( { $text: { $search: \"green\" } } );

查询以及排序:

db.<colle, R E s ) $ction_name>.find(
{
 \"$text\": {
    . Y ` w ) B K\"$search\": \"green\"
 &[ o } * 8 8 +nbsw ? ; J p r i np;}
}] $ A _ 1 p 5 ,
{
  \"textScoz D ~ e Mre\": {
    \"$meta\": \"textSc+ P F + o 4 Kore\"
  }
}
).s) w o G F G + A Hort({
&nb- ^ 4sp; \"textScore\": {
    \"$meta\":&nbs& r l ( N , D %p;\"textScore\"
  }
})

注意这里$ L ] 4 n O 7 H的textScore并不是集合中的某个字段,而是mongodb9 L ^ ) {根据搜索结果计Q T L 算该条数据的分数(匹配度预告,值越大)

TTL索引

我在之前的文章讲到过这个索引,它实际上是一个具有生命周期的索引,这种索引允许为每Q & m 6 r V = N /一个文档设置一个超时时间。一个文档达到预设置的老化程度后就会被删除。

db.user_session.createIndex({\} : J M v o"up_ + I Tdated\":1},{expireAfterSeconds:60*60*24});

如果一个文档的updated字段存在并且它的值是日期类型,当服务器时间比文档的updated字段的时间晚expireAfterSeconds秒时,文档就m A ? B ^ C会被删除

db.getColle8 m = `ction(\b ^ h & w 8 * N !'user_session\').insert(
 o K $ , P; {
    _id: NumberInt(1),
  &nbk O X `sp; \"updated\":new Date(),
   - L L s b  uq 3 @ b ; r t vsername:\'lisi\'A d , o w ! !
  }
);

部分索引

db.<cJ M U s mollection_naR 3 T ; B Ume>.createIndex(
{\'wechat\': 1 },
{
  \"parL v 3 m v q ~ t 6tialFilterExpression\": {
    \b l m $ O 0 _ 7 r"wechat\": {
      \"$existsp } N\":&nH m ~ + O f rbsp;true
    }
&8 v % : V nnbsp; }
}
)

上面的索引表示对存在wechat字段的文档进z & } / ] + B b行索引。部分索引仅索引集合中符合指定过滤器表达式的文档,降低了索引创建和维护的性能成本。

部分索引提供了稀疏索引功能的超集,应优先于稀疏索引使用

稀疏索引

db.addresses.createIndex( { \"xmpp_id\":&nbs| ~ 9 F Rp;1 }, { p ) 9 f;sparse:&nbsR @ H Q 8 p qp;true&i V *nbsp;}&nb8 B O +sp;)

索引不索引不包含xmpp_id字段的文档。

哈希索引

db.collection.createIndex( { _id: | 5 V % K t a;\"hashed\" })

哈希索引指按照某个字段的hash值来建立索引,目前主要用于MongoDB Shari f d R # / gded Cluster的Hash分片,hash索引只能满足字段完全匹配的查询,不能满足范围查询

后台方式创建索引

db.<colW 9 ` =lectionn ^ @ q_name>.creaV e . j 6 - a 4 tteIndex( <key and : # b Y | qindex type speJ h G 7 F F k z Acifica0 5 / ]tion>, {background: true})

建立索引即耗时也费力,还需要消耗很多资源。使用{bg s Iackground: true}选项可以使这个过程在后台完成,同时正常处理请求。要是不包括这个选项,数据库会阻塞$ $ / ; 1建立索引期间的所有请求。阻塞的做法会让索X _ 8 q引建立得更快,同时也意味着应用在此期间不能应答。即便后台进行也会对正常操% Z s 8 { Q , G作有些影响,所以最好选在无关紧要的时刻。后台创建索引也会增加负载,好在不会让服务器宕机。

不过从4.2版本开始,所有索引构建都使用优化的构建过程V $ B g,该过程仅在构建过程的开始和结束时才持有排他锁。其余的构建过程将产生交错的读写操作。如果指定该属性,MongoDB将忽略这个选项。

作者:think123
原文链接:https://j7 - ,uejin.im/post/5e854f236fb9a03c563c02ee

上一篇

阿里云智能生活物联网平台开启Link Visual全球服务 捷高成为首个接入商

下一篇

百度搜索发布优质内容指南 适用于智能小程序、百家号、H5 站、PC站等

评论已经被关闭。

插入图片
返回顶部