前面的話

  索引通常能夠極大的提高查詢的效率,如果沒(méi)有索引,MongoDB在讀取數(shù)據(jù)時(shí)必須掃描集合中的每個(gè)文件并選取那些符合查詢條件的記錄。這種掃描全集合的查詢效率是非常低的,特別在處理大量的數(shù)據(jù)時(shí),查詢可以要花費(fèi)幾十秒甚至幾分鐘,這對(duì)網(wǎng)站的性能是非常致命的。本文將詳細(xì)介紹MongoDB數(shù)據(jù)庫(kù)索引

 

引入

  索引能夠提高查詢效率,如何體現(xiàn)呢?接下來(lái)使用性能分析函數(shù)explain()來(lái)進(jìn)行分析說(shuō)明

  首先,插入10萬(wàn)條數(shù)據(jù)

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  接著,不創(chuàng)建索引,來(lái)尋找time范圍在100和200之間的文檔

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  由圖中所知,totalDocsExamined值為100000,表示查找了100000個(gè)文檔;nReturned值為101,表示返回了101個(gè)文檔;executionTimeMillis值為39,表示花費(fèi)了39ms

  下面,我們?cè)趖ime字段上建立索引

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  再次,尋找time范圍在100和200之間的文檔

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  由圖可知,totalDocsExamined和nReturned值都是101,executionTimeMillis值為0,相當(dāng)于從101個(gè)文檔中,找到了101個(gè)文檔,查找的速度趨近于0。由此可見(jiàn),使用索引極大地提升了查詢速度

 

概述

  索引是特殊的數(shù)據(jù)結(jié)構(gòu),以易于遍歷的形式存儲(chǔ)數(shù)據(jù)集的一小部分。 索引存儲(chǔ)特定字段或一組字段的值,按照索引中指定的字段值排序

  使用索引,可以加快索引相關(guān)的查詢,也相應(yīng)地帶來(lái)一些壞處

  1、增加磁盤空間的消耗。在索引比較多的情況下,索引文件所占據(jù)的空間有可能超過(guò)數(shù)據(jù)本身

  2、在寫(xiě)入數(shù)據(jù)或更新數(shù)據(jù)時(shí),對(duì)索引的維護(hù)一般是寫(xiě)之外的另一條邏輯,一定程度上,會(huì)降低寫(xiě)入性能

  但是,為了查詢的高效,這些影響是值得的。有很多情況下,系統(tǒng)的性能下降,與不合理的索引創(chuàng)建有關(guān)。所以,合理的創(chuàng)建索引,可以減少索引帶來(lái)的不好的影響

 

索引設(shè)置

【getIndexes()】

  使用getIndexes()方法來(lái)查詢索引

db.collection_name.getIndexes()

  由下圖可知,有"_id"和"time"兩個(gè)索引

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

【createIndex()】

db.COLLECTION_NAME.createIndex({KEY:1})

  語(yǔ)法中Key值為要?jiǎng)?chuàng)建的索引字段,1為指定按升序創(chuàng)建索引,如果想按降序來(lái)創(chuàng)建索引指定為-1即可

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn) 

  當(dāng)然,也可以創(chuàng)建多個(gè)索引字段

db.COLLECTION_NAME.createIndex({k1:1,k2:1})

  在MongoDB3.0版本之前,使用的是ensureIndex()方法,現(xiàn)在ensureIndex()方法依然可以使用,只是createIndex()方法的別名

  如果文檔較多,創(chuàng)建索引需要耗費(fèi)一定的時(shí)間。如果系統(tǒng)負(fù)載較重,且有很多已經(jīng)存在的文檔,不能直接使用這個(gè)命令進(jìn)行創(chuàng)建,需要在使用數(shù)據(jù)庫(kù)之前,就將索引創(chuàng)建完畢。否則,嚴(yán)重影響數(shù)據(jù)庫(kù)的性能

  [注意]索引可以重復(fù)創(chuàng)建,如果對(duì)已經(jīng)存在的索引再次創(chuàng)建,會(huì)直接返回成功

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  createIndex() 接收可選參數(shù),可選參數(shù)列表如下:

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

Parameter     Type      Description
background    Boolean    建索引過(guò)程會(huì)阻塞其它數(shù)據(jù)庫(kù)操作,background可指定以后臺(tái)方式創(chuàng)建索引,默認(rèn)值為false
unique        Boolean    建立的索引是否唯一。指定為true創(chuàng)建唯一索引。默認(rèn)值為false
name          string     索引的名稱。如果未指定,MongoDB通過(guò)連接索引的字段名和排序順序生成一個(gè)索引名稱
dropDups      Boolean    在建立唯一索引時(shí)是否刪除重復(fù)記錄,指定 true 創(chuàng)建唯一索引。默認(rèn)值為 falsesparse        Boolean    對(duì)文檔中不存在的字段數(shù)據(jù)不啟用索引;如果設(shè)置為true,索引字段中不會(huì)查詢出不包含對(duì)應(yīng)字段的文檔。默認(rèn)值為falsev             index version    索引的版本號(hào)。默認(rèn)的索引版本取決于mongod創(chuàng)建索引時(shí)運(yùn)行的版本
weights       document   索引權(quán)重值,數(shù)值在 1 到 99,999 之間,表示該索引相對(duì)于其他索引字段的得分權(quán)重
expireAfterSeconds  integer   指定一個(gè)以秒為單位的數(shù)值,完成 TTL設(shè)定,設(shè)定集合的生存時(shí)間
default_language    string    對(duì)于文本索引,該參數(shù)決定了停用詞及詞干和詞器的規(guī)則的列表。 默認(rèn)為英語(yǔ)
language_override   string    對(duì)于文本索引,該參數(shù)指定了包含在文檔中的字段名,默認(rèn)值為language

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

db.db_coll1.createIndex({time:1},{background:true})

【dropIndex()】

  使用db.collection_name.dropIndex({key:1})方法可以刪除指定索引

db.collection_name.dropIndex({key:1})

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  [注意]_id索引無(wú)法被刪除

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  除了使用鍵值對(duì)來(lái)刪除索引,還可以使用其name值來(lái)刪除索引

  如下所示,{time:1}的name值為"time_1",使用db.db_coll1.dropIndex("time_1")也可以刪除索引

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

【dropIndexes()】

  使用db.collection_name.dropIndexes()方法可以刪除所有索引

db.collection_name.dropIndexes()

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

 

索引屬性

【TTL】

  過(guò)期索引又稱為TTL索引,是一種特殊類型的單字段索引,主要用于當(dāng)滿足某個(gè)特定時(shí)間之后自動(dòng)刪除相應(yīng)的文檔。也就是說(shuō)集合中的文檔有一定的有效期,超過(guò)有效期的文檔就會(huì)失效,會(huì)被移除。也即是數(shù)據(jù)會(huì)過(guò)期。過(guò)期的數(shù)據(jù)無(wú)需保留,這種情形適用于如機(jī)器生成的事件數(shù)據(jù),日志和會(huì)話信息等等

  同樣地,過(guò)期索引使用createIndex()方法來(lái)創(chuàng)建,但它支持第二個(gè)參數(shù)expireAfterSeconds,用來(lái)指定多少秒過(guò)期或者包含過(guò)期日期值的數(shù)組

 db.eventlog.createIndex( { x: 1 }, { expireAfterSeconds: 3600 } )

  以下示例中,在60s后,會(huì)刪除time文檔

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  使用過(guò)期索引,有以下幾點(diǎn)注意事項(xiàng)

  1、存儲(chǔ)在過(guò)期索引字段的值必須是指定的時(shí)間類型。必須是ISODate或者ISODate數(shù)組,不能使用時(shí)間戳,否則不能被自動(dòng)刪除

  以下示例中time設(shè)置了ISODate類型的值,該值到60s后會(huì)被自動(dòng)刪除

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  以下示例中,time設(shè)置了時(shí)間戳,該值到60s后無(wú)法被刪除

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  2、如果指定了ISODate時(shí)間數(shù)組,則按照最小的時(shí)間進(jìn)行刪除

  3、過(guò)期索引不能是復(fù)合索引

  4、刪除時(shí)間是不精確的。刪除過(guò)程是由后臺(tái)程序每60s跑一次,而且刪除也需要一些時(shí)間,存在誤差。所以,如果設(shè)置的到期時(shí)間與當(dāng)前時(shí)間的間隔小于60s,則文檔最少也要60s才能被刪除

【唯一性】

  索引的屬性可以具有唯一性,即唯一索引,只要設(shè)置索引屬性中的unique為true即可,默認(rèn)為false。唯一索引用于確保索引字段不存儲(chǔ)重復(fù)的值,即強(qiáng)制索引字段的唯一性。缺省情況下,mongodb的_id字段在創(chuàng)建集合的時(shí)候會(huì)自動(dòng)創(chuàng)建一個(gè)唯一索引

db.collection_name.createIndex({},{unique:true})

  如下圖所示,在默認(rèn)情況下,不是唯一索引

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  在設(shè)置unique:true后,不能插入重復(fù)的值

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

常見(jiàn)錯(cuò)誤

  如下圖所示,設(shè)置的a字段為唯一索引,b字段也無(wú)法輸入重復(fù)的值。這是因?yàn)樵O(shè)置a字段為唯一索引,插入數(shù)據(jù)b:10,相當(dāng)于a:null,再插入b:10時(shí),相當(dāng)于又插入了a:null。而a:null和a:null是重復(fù)的,而a字段是唯一索引,無(wú)法重復(fù)。所以,無(wú)法插入重復(fù)的b:10

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

【稀疏性】

  索引的屬性可以具有稀疏性,即稀疏索引,只要設(shè)置索引屬性中的sparse為true即可,默認(rèn)為false

db.collection_name.createIndex({},{sparse:true})

  稀疏性的不同代表了MongoDB在處理索引中存在但文檔中不存在的字段的兩種不同的方法

  稀疏索引,也稱為間隙索引就是創(chuàng)建索引的索引列在某些文檔上列不存在,導(dǎo)致索引存在間隙。

  假設(shè),在一個(gè)集合中,創(chuàng)建了x字段上的索引。但是,插入的文檔中并不包含x字段。在默認(rèn)情況下,MongoDB依然會(huì)為這條不存在的字段創(chuàng)建索引。如果把這條索引創(chuàng)建為稀疏索引,則這條索引將不會(huì)被使用

  如果數(shù)據(jù)集合中很多文檔在創(chuàng)建索引的字段上并沒(méi)有值,使用稀疏索引可以減少磁盤占用,且提高插入速度

$exits

  使用稀疏索引時(shí),可能會(huì)帶來(lái)一些隱患。MongoDB提供了一種$exits操作符,$exits表示字段是否存在

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  由下圖所示,創(chuàng)建了{(lán)m:1}的稀疏索引,使用find()方法查找不存在m字段的文檔時(shí),結(jié)果出現(xiàn)了。是因?yàn)?,MongoDB并沒(méi)有使用稀疏索引來(lái)查詢

  如果使用hint()方法強(qiáng)制使用稀疏索引來(lái)查找索引上存在而文檔中不存在的字段,則沒(méi)有結(jié)果。再次說(shuō)明稀疏索引不能用來(lái)查找索引上存在,但文檔里不存在的字段

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

 

索引種類

  MongoDB支持基于集合文檔上任意列創(chuàng)建索引。缺省情況下,所有的文檔的_id列上都存在一個(gè)索引。基于業(yè)務(wù)的需要,可以基于一些重要的查詢和操作來(lái)創(chuàng)建一些額外的索引。這些索引可以是單列,也可是多列(復(fù)合索引),多鍵索引,地理空間索引,全文索引等

  MongoDB支持6種索引,包括

  1、_id索引

  2、單鍵索引

  3、多鍵索引

  4、復(fù)合索引

  5、全文索引

  6、地理位置索引

【_id索引】

  _id索引是絕大多數(shù)集合默認(rèn)建立的索引,對(duì)于每個(gè)插入的數(shù)據(jù),MongDB都會(huì)自動(dòng)生成一條唯一的_id字段

  由下圖所示,在未插入任何索引之前,已經(jīng)存在_id索引

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

【單鍵索引】

  單鍵索引是最普通的索引,與_id索引不同,單鍵索引不會(huì)自動(dòng)創(chuàng)建

  比如,一條記錄,形式為{x:1,y:2,z:3},在x字段上建立索引,之后就可以使用x為條件進(jìn)行查詢

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

【多鍵索引】

  在MongoDB中可以基于數(shù)組來(lái)創(chuàng)建索引。mongodb為數(shù)組每一個(gè)元素創(chuàng)建索引值。多鍵索引支持?jǐn)?shù)組字段的高效查詢。多鍵索引能夠基于字符串,數(shù)字?jǐn)?shù)組以及嵌套文檔進(jìn)行創(chuàng)建

  多鍵索引與單鍵索引創(chuàng)建形式相同,區(qū)別在于字段的值。單鍵索引的值為單一的值,如一個(gè)字符串、數(shù)字或日期。多鍵索引的值具有多個(gè)記錄,如一個(gè)數(shù)組

  如果mongoDB中插入數(shù)組類型的多鍵數(shù)據(jù),索引是自動(dòng)建立的,無(wú)需刻意指定。但是,使用getIndexes()方法并沒(méi)有多鍵索引,除非顯式地創(chuàng)建多鍵索引

【復(fù)合索引】

  MongoDB支持復(fù)合索引,即將多個(gè)鍵組合到一起創(chuàng)建索引。該方式稱為復(fù)合索引,或者也叫組合索引,該方式能夠滿足多鍵值匹配查詢使用索引的情形。其次復(fù)合索引在使用的時(shí)候,也可以通過(guò)前綴法來(lái)使用索引

  [注意]任意復(fù)合索引字段不能超過(guò)31個(gè)

  比如,插入{x:1,y:2,z:3}的記錄,當(dāng)需要按照x與y的值進(jìn)行查詢時(shí),就需要?jiǎng)?chuàng)建x與y的復(fù)合索引。接著,就可以使用x和y作為條件進(jìn)行查詢

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

db.db_coll1.createIndex({x:1,y:1})
db.db_coll1.createIndex({x:-1,y:1})
db.db_coll1.createIndex({x:-1,y:-1})
db.db_coll1.createIndex({x:1,y:-1})
db.db_coll1.createIndex({y:1,x:1})
db.db_coll1.createIndex({y:-1,x:1})
db.db_coll1.createIndex({y:-1,x:-1})
db.db_coll1.createIndex({y:1,x:-1})

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  復(fù)合索引創(chuàng)建時(shí)按升序或降序來(lái)指定其排列方式。對(duì)于單鍵索引,其順序并不是特別重要,因?yàn)镸ongoDB可以在任一方向遍歷索引。對(duì)于復(fù)合索引,按何種方式排序能夠決定該索引在查詢中能否被使用到

  x與y的復(fù)合索引共包括以上8種情況,x和y的先后次序不同,升序或降序不同 ,都會(huì)產(chǎn)生不同的索引。而查詢優(yōu)化器,會(huì)使用我們建立的這些索引來(lái)創(chuàng)建查詢方案,最終選擇出最優(yōu)的索引來(lái)查詢數(shù)據(jù)

  索引前綴指的是復(fù)合索引的子集

  假如存在如下索引

{ "item": 1, "location": 1, "stock": 1 }

  那存在下列索引前綴

{ item: 1 }
{ item: 1, location: 1 }

  在MongoDB中,下列查詢過(guò)濾條件情形中,索引將會(huì)被使用到

item字段
item字段 + location字段
item字段 + location字段 + stock字段
item字段 + stock字段(盡管索引被使用,但不高效)

  以下過(guò)濾條件查詢情形,索引將不會(huì)被使用到

location字段
stock字段
location + stock字段

 

全文索引

【創(chuàng)建】

  全文索引也叫做文本索引,常見(jiàn)于搜索框中。我們?cè)谒阉骺蛑休斎腙P(guān)鍵詞,比如 "HTML",不僅標(biāo)題中帶有"HTML"的文章會(huì)被搜索出來(lái),而且文章中存在"HTML"的文章也會(huì)被搜索出來(lái)

  為了索引一個(gè)存儲(chǔ)字符串或者字符串?dāng)?shù)組的鍵,需要在創(chuàng)建選項(xiàng)中包含這個(gè)鍵并指定為 "text" ,如下:

db.reviews.createIndex( { comments: "text" } )

  如果需要在多個(gè)字段上創(chuàng)建全文索引,則可以復(fù)合索引

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

db.reviews.createIndex(
   {
     subject: "text",
     comments: "text"
   }
 )

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  如果需要對(duì)所有字段創(chuàng)建全文索引,則需要使用$xx標(biāo)識(shí)

db.collection_name.createIndex( { "$**": "text" } )

  [注意]一個(gè)集合最多只能創(chuàng)建 一個(gè) 文本 索引

【使用】

  如果使用全文索引進(jìn)行搜索,則需要使用如下格式

db.collection_name.find({$text:{$search: '...'}})

  假設(shè)使用如下的數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)一個(gè)完整的文章,author存儲(chǔ)作者,title存儲(chǔ)標(biāo)題,article存儲(chǔ)文章內(nèi)容

{author:"",title:"",article:""}

  現(xiàn)在來(lái)添加一些數(shù)據(jù),并對(duì)所有字段創(chuàng)建全文索引

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  下面來(lái)搜索'huochai',可搜索到3條記錄

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  如果搜索'a2',則只能搜索到第2條記錄

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  如果搜索'a1 a2 a3',則相當(dāng)于或的關(guān)系,a1 或 a2 或 a3,可以搜索到3條記錄

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  如果搜索'huochai -css',相當(dāng)于查找包含'huochai',但不包含'css'的記錄,包括第1和第3條

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  如果要搜索且關(guān)系,比如同時(shí)包含huochai和css的記錄,則需要在內(nèi)部添加引號(hào)," \"huochai\" \"css\" "

  [注意]只支持雙引號(hào)

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

【相似度】

  全文索引有一個(gè)相似度的概念,表示全文索引的搜索條件與記錄的內(nèi)容有多么相似

  在find()方法的第二個(gè)參數(shù)中,score是一個(gè)數(shù)字,該數(shù)字越大,表示相似度越高

db.collection_name.find({$text:{$search: '...'}},{score:{$meta:"textScore"}})

  現(xiàn)在,再插入一條內(nèi)容,作者為'huochai'

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  然后開(kāi)始搜索'huochai',并帶有相似度

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  下面使用相似度排序,相似度高的排在前面

sort({score:{$meta:"textScore"}})

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

【限制】

  1、每次查詢,只能指定一個(gè)$text查詢

  2、$text查詢不能出現(xiàn)在$nor查詢中

  3、查詢中如果包含了$text,hint()將不再起作用

  4、只能對(duì)整個(gè)單詞查詢,不能對(duì)單詞的截取部分查詢。類似地,中文做全文查詢的時(shí)候,只能查詢一段話中有空格的該字或者詞

前面的話

  索引通常能夠極大的提高查詢的效率,如果沒(méi)有索引,MongoDB在讀取數(shù)據(jù)時(shí)必須掃描集合中的每個(gè)文件并選取那些符合查詢條件的記錄。這種掃描全集合的查詢效率是非常低的,特別在處理大量的數(shù)據(jù)時(shí),查詢可以要花費(fèi)幾十秒甚至幾分鐘,這對(duì)網(wǎng)站的性能是非常致命的。本文將詳細(xì)介紹MongoDB數(shù)據(jù)庫(kù)索引

 

引入

  索引能夠提高查詢效率,如何體現(xiàn)呢?接下來(lái)使用性能分析函數(shù)explain()來(lái)進(jìn)行分析說(shuō)明

  首先,插入10萬(wàn)條數(shù)據(jù)

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  接著,不創(chuàng)建索引,來(lái)尋找time范圍在100和200之間的文檔

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  由圖中所知,totalDocsExamined值為100000,表示查找了100000個(gè)文檔;nReturned值為101,表示返回了101個(gè)文檔;executionTimeMillis值為39,表示花費(fèi)了39ms

  下面,我們?cè)趖ime字段上建立索引

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  再次,尋找time范圍在100和200之間的文檔

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  由圖可知,totalDocsExamined和nReturned值都是101,executionTimeMillis值為0,相當(dāng)于從101個(gè)文檔中,找到了101個(gè)文檔,查找的速度趨近于0。由此可見(jiàn),使用索引極大地提升了查詢速度

 

概述

  索引是特殊的數(shù)據(jù)結(jié)構(gòu),以易于遍歷的形式存儲(chǔ)數(shù)據(jù)集的一小部分。 索引存儲(chǔ)特定字段或一組字段的值,按照索引中指定的字段值排序

  使用索引,可以加快索引相關(guān)的查詢,也相應(yīng)地帶來(lái)一些壞處

  1、增加磁盤空間的消耗。在索引比較多的情況下,索引文件所占據(jù)的空間有可能超過(guò)數(shù)據(jù)本身

  2、在寫(xiě)入數(shù)據(jù)或更新數(shù)據(jù)時(shí),對(duì)索引的維護(hù)一般是寫(xiě)之外的另一條邏輯,一定程度上,會(huì)降低寫(xiě)入性能

  但是,為了查詢的高效,這些影響是值得的。有很多情況下,系統(tǒng)的性能下降,與不合理的索引創(chuàng)建有關(guān)。所以,合理的創(chuàng)建索引,可以減少索引帶來(lái)的不好的影響

 

索引設(shè)置

【getIndexes()】

  使用getIndexes()方法來(lái)查詢索引

db.collection_name.getIndexes()

  由下圖可知,有"_id"和"time"兩個(gè)索引

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

【createIndex()】

db.COLLECTION_NAME.createIndex({KEY:1})

  語(yǔ)法中Key值為要?jiǎng)?chuàng)建的索引字段,1為指定按升序創(chuàng)建索引,如果想按降序來(lái)創(chuàng)建索引指定為-1即可

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn) 

  當(dāng)然,也可以創(chuàng)建多個(gè)索引字段

db.COLLECTION_NAME.createIndex({k1:1,k2:1})

  在MongoDB3.0版本之前,使用的是ensureIndex()方法,現(xiàn)在ensureIndex()方法依然可以使用,只是createIndex()方法的別名

  如果文檔較多,創(chuàng)建索引需要耗費(fèi)一定的時(shí)間。如果系統(tǒng)負(fù)載較重,且有很多已經(jīng)存在的文檔,不能直接使用這個(gè)命令進(jìn)行創(chuàng)建,需要在使用數(shù)據(jù)庫(kù)之前,就將索引創(chuàng)建完畢。否則,嚴(yán)重影響數(shù)據(jù)庫(kù)的性能

  [注意]索引可以重復(fù)創(chuàng)建,如果對(duì)已經(jīng)存在的索引再次創(chuàng)建,會(huì)直接返回成功

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  createIndex() 接收可選參數(shù),可選參數(shù)列表如下:

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

Parameter     Type      Description
background    Boolean    建索引過(guò)程會(huì)阻塞其它數(shù)據(jù)庫(kù)操作,background可指定以后臺(tái)方式創(chuàng)建索引,默認(rèn)值為false
unique        Boolean    建立的索引是否唯一。指定為true創(chuàng)建唯一索引。默認(rèn)值為false
name          string     索引的名稱。如果未指定,MongoDB通過(guò)連接索引的字段名和排序順序生成一個(gè)索引名稱
dropDups      Boolean    在建立唯一索引時(shí)是否刪除重復(fù)記錄,指定 true 創(chuàng)建唯一索引。默認(rèn)值為 falsesparse        Boolean    對(duì)文檔中不存在的字段數(shù)據(jù)不啟用索引;如果設(shè)置為true,索引字段中不會(huì)查詢出不包含對(duì)應(yīng)字段的文檔。默認(rèn)值為falsev             index version    索引的版本號(hào)。默認(rèn)的索引版本取決于mongod創(chuàng)建索引時(shí)運(yùn)行的版本
weights       document   索引權(quán)重值,數(shù)值在 1 到 99,999 之間,表示該索引相對(duì)于其他索引字段的得分權(quán)重
expireAfterSeconds  integer   指定一個(gè)以秒為單位的數(shù)值,完成 TTL設(shè)定,設(shè)定集合的生存時(shí)間
default_language    string    對(duì)于文本索引,該參數(shù)決定了停用詞及詞干和詞器的規(guī)則的列表。 默認(rèn)為英語(yǔ)
language_override   string    對(duì)于文本索引,該參數(shù)指定了包含在文檔中的字段名,默認(rèn)值為language

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

db.db_coll1.createIndex({time:1},{background:true})

【dropIndex()】

  使用db.collection_name.dropIndex({key:1})方法可以刪除指定索引

db.collection_name.dropIndex({key:1})

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  [注意]_id索引無(wú)法被刪除

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  除了使用鍵值對(duì)來(lái)刪除索引,還可以使用其name值來(lái)刪除索引

  如下所示,{time:1}的name值為"time_1",使用db.db_coll1.dropIndex("time_1")也可以刪除索引

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

【dropIndexes()】

  使用db.collection_name.dropIndexes()方法可以刪除所有索引

db.collection_name.dropIndexes()

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

 

索引屬性

【TTL】

  過(guò)期索引又稱為TTL索引,是一種特殊類型的單字段索引,主要用于當(dāng)滿足某個(gè)特定時(shí)間之后自動(dòng)刪除相應(yīng)的文檔。也就是說(shuō)集合中的文檔有一定的有效期,超過(guò)有效期的文檔就會(huì)失效,會(huì)被移除。也即是數(shù)據(jù)會(huì)過(guò)期。過(guò)期的數(shù)據(jù)無(wú)需保留,這種情形適用于如機(jī)器生成的事件數(shù)據(jù),日志和會(huì)話信息等等

  同樣地,過(guò)期索引使用createIndex()方法來(lái)創(chuàng)建,但它支持第二個(gè)參數(shù)expireAfterSeconds,用來(lái)指定多少秒過(guò)期或者包含過(guò)期日期值的數(shù)組

 db.eventlog.createIndex( { x: 1 }, { expireAfterSeconds: 3600 } )

  以下示例中,在60s后,會(huì)刪除time文檔

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  使用過(guò)期索引,有以下幾點(diǎn)注意事項(xiàng)

  1、存儲(chǔ)在過(guò)期索引字段的值必須是指定的時(shí)間類型。必須是ISODate或者ISODate數(shù)組,不能使用時(shí)間戳,否則不能被自動(dòng)刪除

  以下示例中time設(shè)置了ISODate類型的值,該值到60s后會(huì)被自動(dòng)刪除

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  以下示例中,time設(shè)置了時(shí)間戳,該值到60s后無(wú)法被刪除

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  2、如果指定了ISODate時(shí)間數(shù)組,則按照最小的時(shí)間進(jìn)行刪除

  3、過(guò)期索引不能是復(fù)合索引

  4、刪除時(shí)間是不精確的。刪除過(guò)程是由后臺(tái)程序每60s跑一次,而且刪除也需要一些時(shí)間,存在誤差。所以,如果設(shè)置的到期時(shí)間與當(dāng)前時(shí)間的間隔小于60s,則文檔最少也要60s才能被刪除

【唯一性】

  索引的屬性可以具有唯一性,即唯一索引,只要設(shè)置索引屬性中的unique為true即可,默認(rèn)為false。唯一索引用于確保索引字段不存儲(chǔ)重復(fù)的值,即強(qiáng)制索引字段的唯一性。缺省情況下,mongodb的_id字段在創(chuàng)建集合的時(shí)候會(huì)自動(dòng)創(chuàng)建一個(gè)唯一索引

db.collection_name.createIndex({},{unique:true})

http://www.cnblogs.com/xiaohuochai/p/7198461.html