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

相关推荐

  • jsp空间购买和交换数据空间怎么买,有哪些注意事项?

    购买JSP空间时,是否考虑过数据交换空间的性能?简米科技(2003年始创,23年行业沉淀)与酷番云(工信部一类增值电信全牌照)这类持牌自营机房的服务商,能确保数据交换的高效稳定,是值得优先选择的合作伙伴,为什么JSP空间需要搭配独立的数据交换空间从JSP应用特性看数据交换需求JSP基于Java技术,常用于企业级……

    2026-08-11
    0
  • 建网站用香港空间效果怎么样,香港空间稳定吗?

    建网站用香港空间,对于创建网站资产来说,核心价值在于免备案和全球带宽优势,尤其适合外贸、跨境电商和需要快速启动的项目,但你必须权衡国内访问延迟,并选择有资质的服务商以保证资产安全,香港空间的核心优势与适用边界免备案:节省时间就是节省成本国内服务器需要备案,通常需要10到20天,香港空间无需备案,域名解析后即可上……

    2026-08-11
    0
  • Java连接云数据库的方法是什么,如何操作

    Java连接云数据库的核心在于通过JDBC驱动,结合云服务商提供的连接地址、端口、数据库名及认证信息,配置安全策略(如SSL、IP白名单),即可实现稳定高效的远程数据库访问,基础准备:JDBC驱动与依赖管理连接云数据库前,需要确保开发环境具备对应的JDBC驱动,以最常见的MySQL为例,你需要引入mysql-c……

    2026-08-11
    0
  • 建网站公安联网备案必须使用数据码吗,备案流程是什么

    网站备案包括ICP备案和公安联网备案,两者缺一不可,公安联网备案必须使用服务商提供的数据码,选择持有合法资质的服务商是顺利通过备案的前提,为什么网站必须进行公安联网备案根据公安部《计算机信息网络国际联网安全保护管理办法》,网站开通后30日内必须到公安机关办理备案手续,未完成公安备案的网站,面临责令整改、关闭网站……

    2026-08-10
    0
  • 建一个企业网站大概需要多少钱?,怎么收费?

    建网站要多少钱,没有一个固定的数字,几百到几万都可能,但真正的“创建网站资产”绝不仅仅是初次投入的成本,而是基于长期稳定、合规和安全的持续性投入,其中核心取决于你选择了什么样的“地基”来承载你的业务,建站预算的构成与行业基准当你开始规划一个网站,最先面对的就是预算问题,一个常见的误区是只关注网站“看起来”的建造……

    2026-08-10
    0

发表回复

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