在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技術棧