在MongoDB中,可以通过建立索引来进行高效的查询。如果没有索引,MongoDB会扫描整个集合来匹配查询条件,会造成很大的性能消耗。技术博客:Node.js技术栈快速导航Mongodb索引类型索引属性索引实例测试索引(Index)创建库级别锁问题面试指南如何在生产环境中正确创建索引?,参考:#Mongodb索引类型MongoDB提供了不同的索引类型来支持不同业务场景下的查询1._id索引大部分集合默认都被索引。对于每个插入的数据,MongoDB都会生成一个唯一的_id字段。比如新建一个集合db.demo_admin2.insert({x:1})db.demo_admin2.getIndexes()#查看集合索引,可以看到_id索引2.单键索引是最常见的索引,单键索引是不会自动创建的。比如一条记录,形式为:{x:1,y:2,z:3},只要在x字段上建立索引,就可以以x为条件查询db.demo_admin2.ensureIndex({x:1})#创建索引db.demo_admin2.find({x:1});#使用索引查询3.多键索引多键索引和单键索引的区别在于多键索引的值有多条记录,是一个数组db.demo_admin2.insert({x:[1,2,3,4]})4.复合索引当有多个查询条件时,需要创建复合索引插入记录{'x':1,'y':2,'z':3}db.demo_admin2.insert({'x':1,'y':2,'z':3});createindexdb.demo_3.ensureIndex({x:1,y:1})#1升序,-1降序以{x:1,y:1}为条件查询db.demo_admin2.find({x:1,y:2})5.Expiredindex表示一段时间后会过期索引会在一段时间后过期。索引过期后,相应的数据将被删除。适合存放一些过段时间就会失效的数据,比如用户登录信息,这样就不需要使用session了。5.1创建过期索引在创建索引时,还需要使用一个参数来指定索引的有效时间——expireAfterSeconds,单位为秒。下面示例为时间字段创建过期索引db.demo_3.ensureIndex({time:1},{expireAfterSeconds:10})5.2过期索引的限制过期索引字段的值必须是指定的时间类型,必须是ISODate或ISODate数组,不能使用时间戳,否则无法自动删除。如果指定了ISODate数组,则按照最短时间删除。过期索引不能是复合索引。删除时间不准确,删除过程是后台程序每60s运行一次,删除也需要一些时间,所以报错。db.demo_3.ensureIndex({time:1},{expireAfterSeconds:30}db.demo_3.insert({time:newDate()});6.全文索引每个集合只允许创建一个索引在mongodb中,不用担心多个索引造成的冲突6.1全文索引的创建创建全文索引的方法类似于创建单键索引或复合索引。value替换为'text',$**匹配集合下的所有创建一个字段的全文索引db.articles.ensureIndex({key:"text"})创建多个字段的全文索引db.articles.ensureIndex({key_1:"text"},{key_2:"text"})为集合中的所有字段创建全文索引db.articles.ensureIndex({"$**":"text"})6.2创建实例索引db.article.ensureIndex({"article":"text"})db.articles.find({$text:{$search:"coffee"}})db.articles.find({$text:{$search:"aabbcc"}})#包含aa或bb或cc数据db.articles.find({$text:{$search:"aabb-cc"}})#包含aa,bb和不包含cc数据的db.articles。find({$text:{$search:"\"aa\"\"bb\"\"cc\""}})#同时包含aa、bb、cc的数据(用""包裹,引号需要用反斜杠\转义)6.3mongodb相似度查询$meta操作符:{score:{$meta:'textScore'}}查询结果相似度,搜索结果会多一个score字段,分数越高,相关性越高。db.article.find({$text:{$search:"aabbff"}},{score:{$meta:"textScore"}})加上.sort方法可以排序db.article.find({$text:{$search:"aabbff"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}})6.4每次全局索引限制查询,只能指定一个$text查询。$text查询不能出现在$nor查询中。如果$text包含在查询中,提示将不再有效。MongoDB全文索引暂不支持中文。7.地理位置索引2d索引,用于存储和查找平面上的点2dsphere索引,用于存储和查找球面上的点索引属性1.索引属性nameMongoDB会自动创建,规则为key_1orkey_-11或-1代表排序方向,一般影响不大,length一般有125字节的限制db.collection.ensureIndex({indexValue},{name:key})才能看到name,我们可以自己命名为db.demo_3.ensureIndex({x:1,y:1,z:1,n:1},{name:'xyz-name'});删除索引db.demo_3.dropIndex(indexName)2。索引属性unique的唯一性指定类似关系数据库字段的唯一性约束db.demo_3.ensureIndex({m:1,n:1},{unique:true})索引实例测试创建500万条数据,其中分别用于测试索引和非索引之间的差异。它仅在大量数据下有效。在下面的例子中每台电脑配置的耗时值是不同的,在不同的电脑上测试也会有不同的差异。Createtestdata>for(vari=0;i<5000000;i++)db.demo_user.insert({id:i})WriteResult({"nInserted":1})数据查询没有索引在这种情况下,它执行数据查询需要超过6秒。建立索引时查询数据db.getCollection('demo_user').ensureIndex({"id":1})#建立索引下图是建立索引的情况。数据查询只用了0.001秒,可见索引性的重要性。索引导致的库级锁是一个很坑爹的事情。MongoDB没有像MySql和Oracle那样的行级粒度锁的概念。在MongoDB中,只有库级粒度锁的概念,也就是说,当你在生产环境中不小心触发了锁,操作写锁时,其他业务也会受到影响。在MongoDB中创建索引是一个触发写锁的过程。通常,数据量越大,创建的索引占用的写锁时间就越长。在MongoDB中创建索引有两种方法。前台创建(错误)下面是前台创建索引的演示。可以看到执行创建索引命令后,会打开一个新的终端查询另外一张表,处于等待状态,直到索引创建完成后才返回数据。db.getCollection('demo_user').ensureIndex({"id":1})#后台创建索引(推荐)基于后台创建索引的方式执行创建索引的命令后,打开一个新终端查询另一个集合数据可以立即返回。db.getCollection('demo_user').ensureIndex({"id":1},{background:1})#构建索引作者:JunMay链接:https://www.imooc.com/article...来源:MOOCGithub首发:Node.js技术栈推荐阅读MongoDBIndexesGithub:MongoDBIndex
