MongoDB中索引的创建和使用详解

索引通常能够极大的提高查询的效率。在系统中使用查询时,应该考虑建立相关的索引。在MongoDB中创建索引相对比较容易。

MongoDB中的索引在概念上和大多数关系型数据库如MySQL是一样的。当你在某种情况下需要在MySQL中建立索引,这样的情景同样适合于MongoDB。

基本操作

索引是一种数据结构,他搜集一个集合中文档特定字段的值。MongoDB的查询优化器能够使用这种数据结构来快速的对集合(collection)中的文档(collection)进行寻找和排序.准确来说,这些索引是通过B-Tree索引来实现的。

在命令行中,可以通过调用ensureIndex()函数来建立索引,该函数指定一个到多个需要索引的字段。沿用在前面的随笔中的例子,我们再things集合中的j字段上建立索引:

  1. > db.things.ensureIndex({j:1}) 

EnsureIndex()函数自是在索引不存在的情况下才会创建。

一旦集合在某一个字段上建立索引后,对该字段的随机查询的访问速度会很快。如果没有索引,MongoDB会在遍历所有的键值对,然后去对应检查相关的字段。

  1. > db.things.find({j:2}); //在建立了索引的字段上查询,速度快  
  2.  
  3. { "_id" : ObjectId("4e24433dcac1e3490b9033be"), "x" : 4, "j" : 2 }  
  4.  
  5. > db.things.find({x:3});//在未建立索引的字段上查询,需要逐个字段匹配,速度慢  
  6.  
  7. { "_id" : ObjectId("4e244315cac1e3490b9033bc"), "x" : 3 } 

通过在命令行中输入getIndexs()能够查看当前集合中的所有索引。

  1. > db.things.getIndexes()  
  2.  
  3. [  
  4.  
  5. {  
  6.  
  7. "name" : "_id_",  
  8.  
  9. "ns" : "things.things",  
  10.  
  11. "key" : {  
  12.  
  13. "_id" : 1  
  14.  
  15. },  
  16.  
  17. "v" : 0  
  18.  
  19. },  
  20.  
  21. {  
  22.  
  23. "_id" : ObjectId("4e244382cac1e3490b9033d0  
  24.  
  25. "ns" : "things.things",  
  26.  
  27. "key" : {  
  28.  
  29. "j" : 1  
  30.  
  31. },  
  32.  
  33. "name" : "j_1",  
  34.  
  35. "v" : 0  
  36.  
  37. }  
  38.  

通过db.system.indexes.find()能够返回当前数据库中的所有索引

  1. > db.system.indexes.find()  
  2.  
  3. { "name" : "_id_", "ns" : "things.things", "key" : { "_id" : 1 }, "v" : 0 }  
  4.  
  5. { "_id" : ObjectId("4e244382cac1e3490b9033d0"), "ns" : "things.things", "key" :{ "j" : 1 }, "name" : "j_1", "v" : 0 } 

默认索引

对于每一个集合(除了capped集合),默认会在_id字段上创建索引,而且这个特别的索引不能删除。_id字段是强制唯一的,由数据库维护。

嵌套关键字

在MongoDB中,甚至能够在一个嵌入的文档上(embedded)建立索引.

  1. > db.things.ensureIndex({"address.city":1}) 

文档作为索引

任何类型,包括文档(document)都能作为索引:

  1. > db.factories.insert({name:"xyz",metro:{city:"New York",state:"NY"}});  
  2.  
  3. > db.factories.ensureIndex({metro:1});  
  4.  
  5. > db.factories.find({metro:{city:"New York",state:"NY"}});//能够利用索引进行查询  
  6.  
  7. { "_id" : ObjectId("4e244744cac1e3490b9033d2"), "name" : "xyz", "metro" : < 
  8.  
  9. { "city" : "New York", "state" : "NY" } }  
  10.  
  11. > db.factories.find({metro:{$gte:{city:"New York"}}});//能够利用索引进行查询  
  12.  
  13. { "_id" : ObjectId("4e244744cac1e3490b9033d2"), "name" : "xyz", "metro" : { "city" : "New York", "state" : "NY" } }  
  14.  
  15. > db.factories.find({metro:{state:"NY",city:"New York"}})//不能够返回结果,字段的顺序不对 

创建文档索引的一个替代方法是创建复合索引,例如:

  1. > db.factories.ensureIndex({"metro.city":1,"metro.state":1})  
  2.  
  3. > db.factories.find({"metro.city":"New York","metro.state":"NY"});  
  4.  
  5. { "_id" : ObjectId("4e244744cac1e3490b9033d2"), "name" : "xyz", "metro" : { "city" : "New York", "state" : "NY" } }  
  6.  
  7. > db.factories.find({"metro.city":"New York"});  
  8.  
  9. { "_id" : ObjectId("4e244744cac1e3490b9033d2"), "name" : "xyz", "metro" : { "city" : "New York", "state" : "NY" } }  
  10.  
  11. > db.factories.find().sort({"metro.city":1,"New York":1});  
  12.  
  13. { "_id" : ObjectId("4e244744cac1e3490b9033d2"), "name" : "xyz", "metro" : { "city" : "New York", "state" : "NY" } }  
  14.  
  15. > db.factories.find().sort({"metro.city":1});  
  16.  
  17. { "_id" : ObjectId("4e244744cac1e3490b9033d2"), "name" : "xyz", "metro" : { "city" : "New York", "state" : "NY" } } 

组合关键字索引

除了基本的以单个关键字作为索引外,MongoDB也支持多个关键字的组合索引,和基本的索引一样,也是用ensureIndex()函数,该函数可以指定多个键。

  1. > db.things.ensureIndex({j:1,name:-1}) 

当创建索引时,键后面的数字表明了索引的方向,取值为1或者-1,1表示升序,-1表示降序。升序或者降序在随机访问的时候关系不大,当时在做排序或者范围查询的时候就很重要了。

如果在建立了a,b,c这样一个复合索引,那么你可以在a,A,b和a,b,c上使用索引查询。

#p#

稀疏索引

和稀疏矩阵类似,稀疏索引就是索引至包含被索引字段的文档。

任何一个稀疏的缺失某一个字段的文档将不会存储在索引中,之所以称之为稀疏索引就是说缺失字段的文档的值会丢失。

稀疏索引的创建和完全索引的创建没有什么不同。使用稀疏索引进行查询的时候,某些由于缺失了字段的文档记录可能不会被返回,这是由于稀疏索引子返回被索引了的字段。可能比较难以理解,不过看几个例子就好理解了。

  1. > db.people.ensureIndex({title:1},{sparse:true}) //在title字段上建立稀疏索引  
  2.  
  3. > db.people.save({name:"Jim"})  
  4.  
  5. > db.people.save({name:"yang",title:"prince"})  
  6.  
  7. > db.people.find();  
  8.  
  9. { "_id" : ObjectId("4e244dc5cac1e3490b9033d7"), "name" : "Jim" }  
  10.  
  11. { "_id" : ObjectId("4e244debcac1e3490b9033d8"), "name" : "yang", "title" : "prince" }  
  12.  
  13. > db.people.find().sort({title:1})//自有包含有索引字段的记录才被返回  
  14.  
  15. { "_id" : ObjectId("4e244debcac1e3490b9033d8"), "name" : "yang", "title" : "prince" }  
  16.  
  17. > db.people.dropIndex({title:1})//删除稀疏索引之后,所有的记录均显示  
  18.  
  19. { "nIndexesWas" : 2, "ok" : 1 }  
  20.  
  21. > db.people.find().sort({title:1})  
  22.  
  23. { "_id" : ObjectId("4e244dc5cac1e3490b9033d7"), "name" : "Jim" }  
  24.  
  25. { "_id" : ObjectId("4e244debcac1e3490b9033d8"), "name" : "yang", "title" : "prince" } 

唯一索引

MongoDB支持唯一索引,这使得不能插入在唯一索引项上已经存在的记录。例如,要保证firstname和lastname都是唯一的,命令如下

 

  1. > db.things.ensureIndex({firstname:1,lastname:1},{unique:true}) 

缺失的键

当一个文档以唯一索引的方式保存到集合中去的时候,任何缺失的索引字段都会一null值代替,因此,不能在唯一索引上同时插入两条缺省的记录。如下:

  1. >db.things.ensureIndex({firstname: 1}, {unique: true});  
  2.  
  3. >db.things.save({lastname: "Smith"});  
  4.  
  5. >db.things.save({lastname: "Jones"});// 会产生错误,因为firstname会有两个null. 

重复值:

唯一索引不能够创建在具有重复值的键上,如果你一定要在这样的键上创建,那么想系统将保存第一条记录,剩下的记录会被删除,只需要在创建索引的时候加上dropDups这个可选项即可

  1. >db.things.ensureIndex({firstname : 1}, {unique : true, dropDups : true})  
  2.  
  3. Dropping Indexes 

删除一个特定集合上的索引:

  1. >db.collection.dropIndexes(); 

删除集合中的某一个索引:

  1. db.collection.dropIndex({x: 1, y: -1}) 

也可以直接执行命令进性删除

  1. db.runCommand({dropIndexes:'foo', index : {y:1}})//删除集合foo中{y:1}的索引  
  2.  
  3. // remove all indexes:  
  4.  
  5. db.runCommand({dropIndexes:'foo', index : '*'})//删除集合foo中所有的索引 

重建索引:

可以所用如下命令重建索引:

  1. db.myCollection.reIndex()  
  2.  
  3. // same as:  
  4.  
  5. db.runCommand( { reIndex : 'myCollection' } ) 

通常这是不必要的,但是在集合的大小变动很大及集合在磁盘空间上占用很多空间时重建索引才有用。对于大数据量的集合来说,重建索引可能会很慢。

注:

MongoDB中索引是大小写敏感的。

当更新对象是,只有在索引上的这些key发生变化时才会更新。着极大地提高了性能。当对象增长了或者必须移动时,所有的索引必须更新,这回很慢 。

索引信息会保存在system.indexes 集合中,运行 db.system.indexes.find() 能够看到这些示例数据。

索引的字段的大小有最大限制,目前接近800 bytes. 可在大于这个值的字段上建立索引是可以的,但是该字段不会被索引,这种限制在以后的版本中可能被移除。

索引的性能

索引使得可以通过关键字段获取数据,能够使得快速查询和更新数据。

但是,必须注意的是,索引也会在插入和删除的时候增加一些系统的负担。往集合中插入数据的时候,索引的字段必须加入到B-Tree中去,因此,索引适合建立在读远多于写的数据集上,对于写入频繁的集合,在某些情况下,索引反而有副作用。不过大多数集合都是读频繁的集合,所以集合在大多数情况下是有用的。

使用sort()而不需要索引

如果数据集合比较小(通常小于4M),使用sort()而不需要建立索引就能够返回数据。在这种情况下,做好联合使用limit()和sort()。

关于MongoDB索引的创建和使用就介绍到这里,希望能对各位有所帮助,您的收获将是我最大的快乐!

【编辑推荐】

  1. Oracle跟踪文件分析工具TKPROF使用简介
  2. Oracle数据库中Rank等函数的比较与选择
  3. 如何配置Oracle 10g oem中的主机身份证明
  4. 利用Sql Server将Excel中的数据导入Oracle
  5. PLSQL Developer8连接Oracle 10g X64版报错的解决

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/258038.html<

(0)
管理的头像管理
上一篇2025-05-02 01:24
下一篇 2025-05-02 01:25

相关推荐

  • 站群服务器到底是什么意思,怎么选择比较好

    站群服务器就是一台拥有多个独立IP地址、专门用于托管和管理多个网站的高性能服务器,其核心价值在于通过独立IP降低网站间的关联风险,并提升搜索引擎优化效果,站群服务器的工作原理与适用场景站群服务器本质上是将一台物理服务器通过虚拟化或直接配置的方式,分配给多个独立IP地址,每个IP对应一个独立的网站,这些网站共享服……

    2026-07-27
    0
  • 高防服务器误封正常流量如何调整,怎么解决?

    高防服务器误封正常流量,核心调整思路是从“一刀切”转向“精细化”——通过分析业务特征,调整防护阈值、配置白名单和启用智能学习模式,让防护系统学会区分真假流量,为什么会误封正常流量误封主要源于防护策略的通用化,高防服务器通常默认启用严格防护规则,当流量特征与攻击特征库部分匹配时,就会被拦截,据行业安全白皮书指出……

    2026-07-27
    0
  • 高防服务器的防御原理是什么,如何选择高防服务器?

    高防服务器的防御原理,简单说就是通过流量清洗、防火墙规则和黑洞路由等机制,在攻击流量到达业务服务器之前将其过滤或阻断,从而保障正常访问,流量清洗机制是核心防线高防服务器对抗DDoS攻击,靠的不是单一技术,而是一套组合动作,最常见的攻击类型是流量型攻击,比如UDP洪水、SYN洪水、ICMP放大等,核心思路是耗尽带……

    2026-07-26
    0
  • BGP线路到底是什么意思呢,有什么优势?

    BGP线路是一种通过边界网关协议实现多运营商网络互联的接入方式,能自动选择最优路径,极大提升跨网访问速度和稳定性,是解决国内南北网络瓶颈的核心方案,什么是BGP线路BGP,全称Border Gateway Protocol,边界网关协议,是互联网核心路由协议之一,它负责在自治系统之间交换网络可达性信息,BGP线……

    2026-07-26
    0
  • 增值电信业务经营许可证对IDC有多重要,如何办理?

    增值电信业务经营许可证是IDC服务商合法运营的核心凭证,它直接决定了机房能否接入骨干网、客户能否放心托管业务,以及服务商自身能否长期稳定发展,许可证是IDC进入市场的硬门槛互联网数据中心业务属于增值电信业务中的B1类,依据工信部《电信业务经营许可管理办法》,任何从事服务器托管、虚拟主机、云服务等业务的企业,必须……

    2026-07-26
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注