Mongodb06 - 索引

Posted Fallen Lunatic

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mongodb06 - 索引相关的知识,希望对你有一定的参考价值。

1、在任何的数据库之中,索引都是一种提升数据库检索性能的手段,在MongoDB数据库中依然会存在有两种的索引创建:自动创建、手动创建

2、范例:重新创建一个简单的students集合,在students没有设置任何索引,通过getIndexes()函数观察存在的索引内容;=>  

  db.students.getIndexes();  =>  有一个“_id”列的索引内容

  

3、索引创建:db.集合名称.ensureIndex({列 : 1});

    |- 设置的 1 表示索引将按照升序的方式进行排列,降序是 -1;

  (01)、范例:创建一个索引,在age字段上   =>  db.students.ensureIndex({"age": 1});

      

      此时并没有设置索引的名字,索引的名字是自动命名的。命名格式:“字段名称_索引的排序模式

  (02)、针对于age字段上的索引做一个分析  =>  db.students.find({"age": 19}).explain();

      *注:此时的查询使用了索引的技术,但是下面再来观察一个查询,不使用索引查询。

  (03)、针对于score字段上设置查询,不使用索引 => db.students.find({"score": {"$gt": 60}}).explain();

      *注:此时在score字段上并没有设置索引,当前的索引形式变成了全局扫描的模式。

  (04)、如果年龄和成绩一起查询  => db.students.find({"$or": [{"age": {"$gt": 19}},{"score": 60}}).explain();

      这个时候虽然age字段上存在有索引,但是有一个很明显的问题,由于score没有索引,依然使用全表扫描,

      为了解决此事的问题,可以使用复合索引。

  (05)、范例:强制使用索引  =>  db.students.find({"$or": [{"age": {"$gt": 19}},{"score": {"$gt": 19}}]}).hint({"age": -1, "score": -1}).explain();

      如果正常来讲,这个代码根本就不可能调用默认的索引执行,但是我们觉得不好,所以需要使用hint()函数来强制MongoDB告诉你必须使用一次索引,

      由于此时在age个score两个字段上已经使用了符合索引,那么现在使用的就是默认的复合索引;

      但是如果在一个聚合里面设置了过多的索引,实际上会导致性能下降,可以删除索引;

  (06)、删除一个索引   =>  db.students.dropIndex({"age": -1, "score": -1}); 

  (07)、删除全部索引  =>   db.students.dropIndexes();

      所谓删除全部索引指的就是非“_id”的索引,所有的自定义索引。

4、唯一索引

  (01)、唯一索引的主要目的是用在某一个字段上,使该字段的内容不重复。

  (02)、创建唯一索引  =>  db.students.ensureIndex({"name":1},{"unique":true});

      在name字段上的内容绝对不允许重复。

  (03)、增加一条相同的数据,此时除了name字段上的内容之外,发现所有的数据都不一样,但是由于name字段上设置了唯一的索引,

      所以整个程序里面如果增加了重复内容,那么会出现以下的错误内容:

      E11000 duplicate key error index: mldn.students.$name

5、过期索引

  (01)、在一些程序点会出现若干秒之后信息被删除的情况,例如:手机信息验证;

      实现过期索引,但是这个时间往往不怎么准确。

      范例:设置过期索引

        db.phone.ensureIndex({"time": 1}, {expireAfterSeconds: 10});

        设置索引在10秒后过期。

  (02)、范例:在一个phones集合里面设置过期索引

      如果要想实现过期索引,需要保存一个时间 信息

      db.phones.insert({"tel":"110","code":"110","time": new Date()});

      *注:等到10秒以后(永远不会那么准确)所保存的数据就会消失,这样的特性在进行一些临时数据保存的时候非常有帮助,

      如果没有MongoDB这种特性,而且是使用最简单的关系型数据开发,那么非常麻烦。

5、全文索引

  (01)、在一些信息管理的平台上经常需要进行信息模糊查询,最早的时候时候是利用某个字段上实现的模糊查询,但是信息返回不准确,

      在MongoDB里面实现简单的全文检索。

  (02)、范例:定义一个集合(新闻信息)

      db.news.insert({"title":"grh","content":"gry"});

      db.news.insert({"title":"grh","content":"gry"});

      db.news.insert({"title":"sfq","content":"gry"});

      db.news.insert({"title":"fhif","content":"jgasdlkljad"});

  (03)、范例:设置全文检索

       db.news.ensureIndex({"title":"text","content":"text"});

  (04)、范例:实现数据的模糊查询

        如果要想表示出全文检索,则使用“$text”判断符,数据查询使用“$search”运算符

        |- 查询指定关键字:{"$search":"查询关键字"}  =>  db.news.find({"$text": {"$search":"gry"}});

        |- 查询多个关键字(或关系):{"$search":"查询关键字   查询关键字   查询关键字  ....};

        |- 查询多个关键字(与关系):{"$search":"\\"查询关键字"\\"查询关键字"\\"查询关键字"...."}

        |- 查询多个关键字(排除一个):{"$search":"查询关键字   查询关键字   查询关键字  .... - " };

  (05)、为结果打分  - 分越高越好

      打分按照降序排列:db.news.find({"$text": {"$search": "gry"}},{"score":{"$meta":"textScore"}}).sort({"score":{"$meta":"textScore"}}));

      按照打分的成绩进行排序,实际上就可以实现更加准去的信息搜索。

  (06)、为所有字段设置全文检索  =>  db.news.ensureIndex({"$**":"text"});

      这是一种罪简单的设置全文索引的方式(竟可能别用:慢)

6、地理信息索引

  (01)、地理信息索引分为两种:2D平面索引,另外就是2DSphere球面索引。在2D索引中保存的都是坐标,而且坐标保存的就是经纬度坐标。

  (02)、范例:定义一个商铺集合      

        db.shop.insert({"loc": [10,10]});
        db.shop.insert({"loc": [11,10]});
        db.shop.insert({"loc": [10,11]});
        db.shop.insert({"loc": [16,17]});
        db.shop.insert({"loc": [50,60]});
        db.shop.insert({"loc": [90,90]});
        db.shop.insert({"loc": [120,130]});

      范例:为shop的集合定义2D索引   =>  db.shop.ensureIndex({"loc":"2d"});

      这个时候shop集合就可以实现坐标位置的查询了,而要进行查询有两种操作:

        “$near”查询:查询距离某个点最近的坐标点;

        “$geoWithin”查询:查询某个性状内的点;

      范例:查询距离坐标[11,11]最近的5个点  =>  db.shop.find({loc:{"$near":[11,11],"$maxDistance":5}});

         但是需要注意,在2D索引里面虽然支持最大距离,不支持最小距离;

         但是也可以设置一个查询的范围,使用“$geoWithin”查询,而可以设置几种操作:

           矩形范围($box):{"$box": [[x1,y1],[x2,y2]]};

             db.shop.find({loc:{"$geoWithin":[[9,9],[11,11]]}});

           圆形范围($center):{"$center":[[x1,y1],r]};

           多边形($polygon): {"$polygon":[[x1,y1],[x2,y2],[x3,y3],.....]}

  (03)、MongoDB里面,除了一些支持的操作函数之外,还有一个重要的命令:runCommand(),

      这个函数可以执行所有的特定MongoDB命令。

      范例:利用runCommand()实现信息查询   =>  db.runCommand({"geoNear":"shop", near:[10,10],maxDistance:5,num:2});

      这类的命令可以说是MongoDB之中最为基础的命令。

以上是关于Mongodb06 - 索引的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB - 如何提高创建索引的性能?

mongoDB没有选择索引

唯一索引不适用于 Mongoose / MongoDB

不同类型的 MongoDB 索引

mongodb地理定位索引和查询

使用 2dsphere 索引和 IP 地址索引索引 mongodb 集合