学习MongoDB 七: MongoDB索引(索引基本操作)(一)

一、简介

在MongoDB建立索引能提高查询效率,只需要扫描索引只存储的这个集合的一小部分,并只把这小部分加载到内存中,效率大大的提高,如果没有建立索引,在查询时,MongoDB必须执行全表扫描,在数据量大时,效率差别就很明显,对于包括一个没有索引的排序操作的查询,服务器必须在返回任何结果之前将所有的文档加载到内存中来进行排序。

索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构。索引项的排序支持高效的相等匹配和基于范围的查询操作。

从mongoDB 3.0开始ensureIndex被废弃,使用 createIndex创建索引。

创建索引的语法:

     db.collection.createIndex(keys,options)

参数


类型


描述


keys


document


一个包含该字段的字段和值对的文档,该文档的索引键和该值描述该字段的索引类型。对于某个领域的上升索引,指定一个值为1;对于下降的索引,指定一个值为1。

MongoDB支持几种不同的索引类型,包括文本,空间,和哈希索引。查看更多信息的索引类型。


options


document


在创建索引的时的限制条件

二、 索引的基本操作

我们先插入10w条记录

 for(var i=0;i<1000000;i++){
.       db. orders.insert({
         "onumber" : i,
         "date" : "2015-07-02",
         "cname" : "zcy"+i,
          "items" :[ {
                   "ino" : i,
                  "quantity" : i,
                  "price" : 4.0
            },{
                  "ino" : i+1,
                  "quantity" : i+1,
                  "price" : 6.0
             }
          ]
    })
}

1.      默认索引

存储在MongoDB集合中的每个文档(document)都有一个默认的主键“_id“,如果我们在添加新的文档时,没有指定“_id“值时,MongoDB会创建一个ObjectId值,并创建会自动创建一个索引在“_id“键上,默认索引的名称是”_id_“,并无法删除,如下面的命令查看:

     >db.orders.getIndexes()

2.       查看索引信息

返回一个数组,该数组保存标识和描述集合上现有索引的文档列表,可以查看我们是否有对某个集合创建索引,并创建哪些索引,方便我们管理。

语法:

          >db.collection.getIndexes()

3.      创建单列索引

我们对文档单个字段创建索引或者对内嵌文档的单个字段创建索引

语法:

           db.collection.createIndex({field:boolean} })

boolean:对于某个领域的上升索引,指定一个值为1;对于下降的索引,指定一个值为1。

(1)创建

例子:

             >db.orders.createIndex({cname:1})      

我们对orders集合创建了cname索引,默认的索引名称是”cname_1“

 (2)根据条件查询文档,并查看查询效率怎么样

例子:

                > db.orders.find({"cname":"zcy100000"})

我们查询orders 集合根据条件cname为zcy100000的文档

我们测试有建索引和没建索引在1000000条文档执行查询的效率怎么样,我们这边先使用explain()函数,下一篇我们介绍

我们这边先介绍几个参数

1) n:当前查询返回的文档数量。

2)millis:当前查询所需时间,毫秒数。

3)indexBounds:当前查询具体使用的索引

例子:

                > db.orders.find({"cname":"zcy100000"}).explain()

   1)没建索引时,查询条件cname为zcy100000的文档

返回一个记录,花费1006毫秒,没使用到索引

2)有建索引,查询条件cname为zcy100000的文档

返回一个记录,花费82毫秒,有使用到cname索引

我们结果是相差很大的,有建索引字段,查询效率比较高,在大数据时,差别更明显。

(3)查询和排序组合使用

我们查询集合cname大于zcy100的文档并对onumber进行降序排序

例子:

            >db.orders.find({"cname":{$gt:"zcy1000"}}).sort({"onumber":1}).explain()

执行出现错误:

"$err" : "Runner error:Overflow sort stage buffered data usage of 33554456 bytes exceeds internal limit of 33554432 bytes",

我们的内存只有33554432字节,对于包括一个没有索引的排序操作的查询,服务器必须在返回任何结果之前将所有的文档加载到内存中来进行排序。

我们对onumber创建索引

           > db.orders.createIndex({onumber:-1})

这次我们在执行时,可以正常执行,已经减少了内存的缓存的数据

4.       创建组合索引

我们可以同时对多个键创建组合索引

语法:

          db.collection.createIndex({field1:boolean, field2:boolean } })

说明:

db.collection.createIndex({a:1,b:1,c:1 } })

我们对a、b、c进组合创建索引,支持查询时会用到索引的几种:

1)      a

2)      a,b

3)      a,b,c

这三中的查询条件,会使用到索引

(1)      创建组合索引

我们同时对onumber和cname进行组合索引

例子:

       >db.orders.createIndex({cname:1,onumber:-1})

索引存储在一个易于遍历读取的数据集合中,存储的数据

{_id:..,"onumber" : 2, "date" : "2015-07-02", "cname" : "zcy1"})

{_id:..,"onumber" : 1, "date" : "2015-07-02", "cname" : "zcy1"})

{_id:..,"onumber" : 1, "date" : "2015-07-02", "cname" : "zcy2"})

(2) 查询

1)我们对cname和onumber作为查询条件时

例子:

           >db.orders.find({"cname":{$gt:"zcy1000"},"onumber":2000}).explain()

我们查询条件cname大于zcy1000并且onumber等于2000的数据,我们用explain()查询索引使用情况

2)我们只用两个索引其中一个作为查询时

第一种情况:我们条件只使用"cname":{$gt:"zcy1000"}作为查询条件

例子:

          >db.orders.find({"cname":{$gt:"zcy1000"}}).explain()

会使用到索引,符合我们前面介绍的我们对a、b、c进组合创建索引,支持查询时会用到索引的第一种。

第二种情况:我们条件只使用"onumber":2000作为查询条件

例子:

         > db.orders.find({"onumber":2000}).explain()

不会使用到索引,不符合我们前面介绍的我们对a、b、c进组合创建索引,支持查询时会用到几种。

(3)查询和排序组合使用

我们查询集合cname大于zcy100的文档并对onumber进行降序排序

例子:

      >db.orders.find({"cname":{$gt:"zcy1000"}}).sort({"onumber":1}).explain()

执行出现错误:

"$err" : "Runner error:Overflow sort stage buffered data usage of 33554456 bytes exceeds internal limit of 33554432 bytes",

sort时,不会使用到索引,不符合我们前面介绍的我们对a、b、c进组合创建索引,支持查询时会用到几种。

总结:我们在使用组合索引时,查询时会用到组合索引的前端的几种组合。

我们对a、b、c进组合创建索引,支持查询时会用到索引的几种:

1)      a

2)      a,b

3)      a,b,c

5.      内嵌文档的索引

我们对内嵌文档创建索引时,跟基本文档创建索引一样

语法:

        db.collection.createIndex({field:boolean} })

field说明:以“.“来指明内嵌文档的路径

(1)      单列的内嵌文档的索引创建

例子:

         >db.orders.createIndex({"items.info":1})

我们orders集合下的内嵌items集合的info字段创建索引

我们以items.info字段作为查询条件,并使用索引的情况

例子:

       >db.orders.find({"items.info":{$lt:100}}).explain()

我们查询items.info小于100的数据

 (2)      组合的内嵌文档的索引的创建

我们对内嵌文档创建组合索引时,跟基本文档创建组合索引一样

语法:

        >db.collection.createIndex({field1:boolean, field2:boolean } })

例子:

       >db.orders.createIndex({"items.info":1, "items. quantity":-1})

6.      删除索引

我们对已经创建的索引进行删除,可以针对具体的集合中索引进行删除,也可以对所有的集合中的所有索引删除

(1)具体索引名称删除索引

语法:

        db.collection.dropIndex(index)

删除具体的索引,根据索引名称删除,如果不知道索引的名称,可以通过db.collection.getIndexes()查看索引名称

例子:

     > db.orders.dropIndex("cname_1")

我们删除cname字段的索引,现在只剩下onumber字段索引

 (2)删除集合中所有索引

语法:

       db.collection.dropIndexes()

例子:

      > db.orders.dropIndexes()

我们对集合中的索引都删除,我们删除cname字段的索引和onumber字段索引,现在只剩默认的_id字段索引,索引我们在使用时,要谨慎,以免把集合中的索引都删除。

  (3)对dropIndexes方法,我们还有一种用法,可以指定集合的具体索引的删除

例子:

     > db.runCommand({"dropIndexes":"orders","index":"cname_1"})

我们删除cname字段的索引,现在只剩下onumber字段索引

总结:

在MongoDB建立索引能提高查询效率,但在MongoDB新增、修改效率上比较慢

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-11 05:31:59

学习MongoDB 七: MongoDB索引(索引基本操作)(一)的相关文章

MongoDB (七) MongoDB 数据类型

MongoDB支持许多数据类型的列表下面给出: String : 这是最常用的数据类型来存储数据.在MongoDB中的字符串必须是有效的UTF-8. Integer : 这种类型是用来存储一个数值.整数可以是32位或64位,这取决于您的服务器. Boolean : 此类型用于存储一个布尔值 (true/ false) . Double : 这种类型是用来存储浮点值. Min/ Max keys : 这种类型被用来对BSON元素的最低和最高值比较. Arrays : 使用此类型的数组或列表或多个值

MongoDB入门学习(四):MongoDB的索引

上一篇讲到了MongoDB的基本操作增删查改,对于查询来说,必须按照我们的查询要求去集合中,并将查找到的结果返回,在这个过程中其实是对整个集合中每个文档进行了扫描,如果满足我们的要求就添加到结果集中最后返回.对于小集合来说,这个过程没什么,但是集合中数据很大的时候,进行表扫描是一个非常恐怖的事情,于是有了索引一说,索引是用来加速查询的,相当于书籍的目录,有了目录可以很精准的定位要查找内容的位置,从而减少无谓的查找. 1.索引的类型 创建索引可以是在单个字段上,也可以是在多个字段上,这个根据自己的

8天学通MongoDB——第四天 索引操作

这些天项目改版,时间比较紧,博客也就没跟得上,还望大家见谅. 好,今天分享下mongodb中关于索引的基本操作,我们日常做开发都避免不了要对程序进行性能优化,而程序的操作无非就是CURD,通常我们 又会花费50%的时间在R上面,因为Read操作对用户来说是非常敏感的,处理不好就会被人唾弃,呵呵. 从算法上来说有5种经典的查找,具体的可以参见我的算法速成系列,这其中就包括我们今天所说的“索引查找”,如果大家对sqlserver比较了解 的话,相信索引查找能给我们带来什么样的性能提升吧. 我们首先插

【转载】8天学通MongoDB——第四天 索引操作

这些天项目改版,时间比较紧,博客也就没跟得上,还望大家见谅. 好,今天分享下mongodb中关于索引的基本操作,我们日常做开发都避免不了要对程序进行性能优化,而程序的操作无非就是CURD,通常我们 又会花费50%的时间在R上面,因为Read操作对用户来说是非常敏感的,处理不好就会被人唾弃,呵呵. 从算法上来说有5种经典的查找,具体的可以参见我的算法速成系列,这其中就包括我们今天所说的“索引查找”,如果大家对sqlserver比较了解 的话,相信索引查找能给我们带来什么样的性能提升吧. 我们首先插

mongoDB常见的查询索引(三)

1. _id索引 _id索引是绝大多数集合默认建立的索引 对于每个插入的数据,MongoDB会自动生成一条唯一的_id字段. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 > db.jerome_2.collection.insert({x:2}) WriteResult({ "nInserted" : 1 }) > db.jerome_2.collection.getIndexes() [     {         "v&quo

MongoDB基础--数据库和集合基本操作

本笔记针对https://www.shiyanlou.com/courses/running/50 网站对mongoDB的学习和总结. 1,启动mongoDB 因为mongoDB服务并不随着系统一起启动,所以需要首先启动mongoDB服务: shiyanlou:~/ $ sudo service mongodb start 2,数据库简介 一个MongoDB可以创建多个数据库. 使用 show dbs可以查看所有数据库的列表 执行db命令则可以查看当前数据库对象或者集合. 运行use命令则可以连

MongoDB学习笔记(一) MongoDB介绍及安装

这是MongoDB的系列学习笔记的第一篇,主要介绍什么是非关系型数据库MongoDB,如何下载,去哪儿下载,又该怎么正确的安装等一系列问题. 一.前言 最近开始学习非关系型数据库MongoDB,却在博客园上找不到比较系统的教程,很多资料都要去查阅英文网站,效率比较低下.本人不才,借着自学的 机会把心得体会都记录下来,方便感兴趣的童鞋分享讨论.部分资源出自其他博客,旨将零散知识点集中到一起,如果有侵犯您的权利,请联系li- [email protected].大部分内容均系原创,欢迎大家转载分享,

MongoDB入门学习(三):MongoDB的增删查改

对于我们这种菜鸟来说,最重要的不是数据库的管理,也不是数据库的性能,更不是数据库的扩展,而是怎么用好这款数据库,也就是一个数据库提供的最核心的功能,增删查改. 因为MongoDB存储数据都是以文档的模式,所以在操作它的数据时,也是以文档为单位的.那么我们实现增删查改也是以文档为基础,不知道文档是什么的同学可以看看上篇介绍的基本概念. 1.插入文档 向MongoDB集合中插入文档的基本方法是insert: 单个插入 > document = {key : value} > db.collecti

MongoDB入门学习(二):MongoDB的基本概念和数据类型

上一篇讲了MongoDB的安装和管理,其中涉及到了一些概念,数据结构还有一些API的调用,不知道的没关系,其实很简单,这篇会简单介绍一下. 1.文档 文档是MongoDB的核心概念,多个键值对有序的放在一起就是一个文档,文档是MongoDB存储数据最基本的数据结构.对MongoDB都是以文档的形式来操作的,使用了一种类似JSON的二进制BSON数据格式,对API的调用都是传的文档参数.每种编程语言都有标示文档的数据结构,比如java的map,lua的table,python的dict等等,但是都