在MongoDB中经过创建索引能够进行高效的查询,若是没有索引MongoDB将会扫描整个集合与查询的条件进行匹配,这对于性能会形成很大的消耗。技术博客: Node.js技术栈git
生产环境如何正确建立索引?
,参考:# MongoDB提供了不一样的索引类型支持在不一样的业务场景进行查询
绝大多数集合默认创建索引,对于每一个插入的数据,MongoDB都会生成一条惟一的_id字段。
例如新建立一个集合时github
db.demo_admin2.insert({x:1}) db.demo_admin2.getIndexes() # 查看集合索引,可看到_id索引
是最普通的索引,单键索引不会自动建立
例如一条记录形式为:{x:1,y:2,z:3},只要在x字段上创建索引以后,就能够用x为条件进行查询面试
db.demo_admin2.ensureIndex({x:1}) # 建立索引 db.demo_admin2.find({x:1}); # 使用索引查询
多键索引与单键索引区别在于多键索引的值具备多个记录,是一个数组
db.demo_admin2.insert({x:[1,2,3,4]})
当查询条件为多个时,须要创建复合索引
插入记录{'x':1,'y':2,'z':3}
mongodb
db.demo_admin2.insert({'x':1,'y':2,'z':3});
建立索引shell
db.demo_3.ensureIndex({x:1,y:1}) # 1升序,-1降序
使用{x:1,y:1}
做为条件进行查询数据库
db.demo_admin2.find({x:1,y:2})
指在一段时间后会过时的索引,此索引过一段时间会过时,索引过时后,相应的数据会被删除,适合存储一些在一段时间以后会失效的数据,好比用户登陆信息,这样就不须要用到session了。
5.1 建立过时索引数组
创建索引的时候须要多用一个参数,指定索引的有效时间——expireAfterSeconds,单位为秒
以下示例为time
字段建立过时索引session
db.demo_3.ensureIndex({time:1},{expireAfterSeconds:10})
5.2 过时索引限制性能
db.demo_3.ensureIndex({time:1},{expireAfterSeconds:30} db.demo_3.insert({time:new Date()});
在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:"aa bb cc"}}) # 包含aa或bb或cc的数据 db.articles.find({$text:{$search:"aa bb -cc"}}) # 同时包含aa、bb且不包含cc的数据 db.articles.find({$text:{$search:"\"aa\" \"bb\" \"cc\""}})# 同时包含aa、bb、cc的数据(用""包裹起来,引号须要用反斜杠\转义)
6.3 mongodb类似度查询
$meta
操做符:{score:{$meta:'textScore'}}
查询结果的类似度,搜索出的结果会多出一个score字段,这个得分越高,相关度越高。
db.article.find({$text:{$search:"aa bb ff"}},{score:{$meta:"textScore"}})
加上.sort方法可排序
db.article.find({$text:{$search:"aa bb ff"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}})
6.4 全局索引的限制
$text
查询$text
查询不能出如今$nor
查询中$text
, hint
再也不起做用1.索引属性name
MongoDB会自动的建立,规则是key_1 或者 key_-1 1或者-1表明排序方向,通常影响不大,长度通常有限制125字节
db.collection.ensureIndex({indexValue},{name: key})
为了见名知意咱们能够本身来命名
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万条数据,分别用来测试创建索引和未创建索引的差异,只有在大量数据下才有效果,如下的示例中的时间消耗值,各电脑配置的不一样在不一样电脑上测试也会有不一样的差异。
> for(var i=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}) # 创建索引
做者:五月君
连接:https://www.imooc.com/article...
来源:首发慕课网
Github: Node.js技术栈