摘要:復合唯一索引也可以創建復合的唯一索引。中的稀疏索引與關系型數據庫中的稀疏索引是完全不同的概念。但是這里不會指明索引是否是多鍵索引。上一篇文章指南使用和何時不應該使用索引下一篇文章指南特殊的索引和集合固定集合索引全文本索引
上一篇文章:MongoDB指南---12、使用explain()和hint()、何時不應該使用索引
下一篇文章:MongoDB指南---14、特殊的索引和集合:固定集合、TTL索引、全文本索引
創建索引時可以指定一些選項,使用不同選項建立的索引會有不同的行為。接下來的小節會介紹常見的索引變種,更高級的索引類型和特殊選項會在下一章介紹。
唯一索引唯一索引可以確保集合的每一個文檔的指定鍵都有唯一值。例如,如果想保證同不文檔的"username"鍵擁有不同的值,創建一個唯一索引就好了:
> db.users.ensureIndex({"username" : 1}, {"unique" : true})
如果試圖向上面的集合中插入如下文檔:
> db.users.insert({username: "bob"}) > db.users.insert({username: "bob"}) E11000 duplicate key error index: test.users.$username_1 dup key: { : "bob" }
如果檢查這個集合,會發現只有第一個"bob"被保存進來了。發現有重復的鍵時拋出異常會影響效率,所以可以使用唯一索引來應對偶爾可能會出現的鍵重復問題,而不是在運行時對重復的鍵進行過濾。
有一個唯一索引可能你已經比較熟悉了,就是"_id"索引,這個索引會在創建集合時自動創建。這就是一個正常的唯一索引(但它不能被刪除,而其他唯一索引是可以刪除的)。
如果一個文檔沒有對應的鍵,索引會將其作為null存儲。所以,如果對某個鍵建立了唯一索引,但插入了多個缺少該索引鍵的文檔,由于集合已經存在一個該索引鍵的值為null的文檔而導致插入失敗。5.4.2節會詳細介紹相關內容。
有些情況下,一個值可能無法被索引。索引儲桶(index bucket)的大小是有限制的,如果某個索引條目超出了它的限制,那么這個條目就不會包含在索引里。這樣會造成一些困惑,因為使用這個索引進行查詢時會有一個文檔憑空消失不見了。所有的字段都必須小于1024字節,才能包含到索引里。如果一個文檔的字段由于太大不能包含在索引里,MongoDB不會返回任何錯誤或者警告。也就是說,超出8 KB大小的鍵不會受到唯一索引的約束:可以插入多個同樣的8 KB長的字符串。
1. 復合唯一索引也可以創建復合的唯一索引。創建復合唯一索引時,單個鍵的值可以相同,但所有鍵的組合值必須是唯一的。
例如,如果有一個{"username" : 1, "age" : 1}上的唯一索引,下面的插入是合法的:
db.users.insert({"username" : "bob"})2. 去除重復
db.users.insert({"username" : "bob", "age" : 23})
db.users.insert({"username" : "fred", "age" : 23})
然而,如果試圖再次插入這三個文檔中的任意一個,都會導致鍵重復異常。
GirdFS是MongoDB中存儲大文件的標準方式(詳見6.5節),其中就用到了復合唯一索引。存儲文件內容的集合有一個{"files_id" : 1, "n" : 1}上的復合唯一索引,因此文檔的某一部分看起來可能會是下面這個樣子:
{"files_id" : ObjectId("4b23c3ca7525f35f94b60a2d"), "n" : 1}
{"files_id" : ObjectId("4b23c3ca7525f35f94b60a2d"), "n" : 2}
{"files_id" : ObjectId("4b23c3ca7525f35f94b60a2d"), "n" : 3}
{"files_id" : ObjectId("4b23c3ca7525f35f94b60a2d"), "n" : 4}
注意,所有"files_id"的值都相同,但是"n"的值不同。
在已有的集合上創建唯一索引時可能會失敗,因為集合中可能已經存在重復值了:
> db.users.ensureIndex({"age" : 1}, {"unique" : true}) E11000 duplicate key error index: test.users.$age_1 dup key: { : 12 }
通常需要先對已有的數據進行處理(可以使用聚合框架),找出重復的數據,想辦法處理。
在極少數情況下,可能希望直接刪除重復的值。創建索引時使用"dropDups"選項,如果遇到重復的值,第一個會被保留,之后的重復文檔都會被刪除。
> db.people.ensureIndex({"username" : 1}, {"unique" : true, "dropDups" : true})
"dropDups"會強制性建立唯一索引,但是這個方式太粗暴了:你無法控制哪些文檔被保留哪些文檔被刪除(如果有文檔被刪除的話,MongoDB也不會給出提示說哪些文檔被刪除了)。對于比較重要的數據,千萬不要使用"dropDups"。
稀疏索引前面的小節已經講過,唯一索引會把null看做值,所以無法將多個缺少唯一索引中的鍵的文檔插入到集合中。然而,在有些情況下,你可能希望唯一索引只對包含相應鍵的文檔生效。如果有一個可能存在也可能不存在的字段,但是當它存在時,它必須是唯一的,這時就可以將unique和sparse選項組合在一起使用。
MongoDB中的稀疏索引(sparse index)與關系型數據庫中的稀疏索引是完全不同的概念。基本上來說,MongoDB中的稀疏索引只是不需要將每個文檔都作為索引條目。
使用sparse選項就可以創建稀疏索引。例如,如果有一個可選的email地址字段,但是,如果提供了這個字段,那么它的值必須是唯一的:
> db.ensureIndex({"email" : 1}, {"unique" : true, "sparse" : true})
稀疏索引不必是唯一的。只要去掉unique選項,就可以創建一個非唯一的稀疏索引。
根據是否使用稀疏索引,同一個查詢的返回結果可能會不同。假如有這樣一個集合,其中的大部分文檔都有一個"x"字段,但是有些沒有:
> db.foo.find() { "_id" : 0 } { "_id" : 1, "x" : 1 } { "_id" : 2, "x" : 2 } { "_id" : 3, "x" : 3 }
當在"x"上執行查詢時,它會返回相匹配的文檔:
> db.foo.find({"x" : {"$ne" : 2}}) { "_id" : 0 } { "_id" : 1, "x" : 1 } { "_id" : 3, "x" : 3 }
如果在"x"上創建一個稀疏索引,"_id"為0的文檔就不會包含在索引中。如果再次在"x"上查詢,MongoDB就會使用這個稀疏索引,{"_id" : 0}的這個文檔就不會被返回了:
> db.foo.find({"x" : {"$ne" : 2}}) { "_id" : 1, "x" : 1 } { "_id" : 3, "x" : 3 }
如果需要得到那些不包含"x"字段的文檔,可以使用hint()強制進行全表掃描。
索引管理如前面的小節所述,可以使用ensuerIndex函數創建新的索引。對于一個集合,每個索引只需要創建一次。如果重復創建相同的索引,是沒有任何作用的。
所有的數據庫索引信息都存儲在system.indexes集合中。這是一個保留集合,不能在其中插入或者刪除文檔。只能通過ensureIndex或者dropIndexes對其進行操作。
創建一個索引之后,就可以在system.indexes中看到它的元信息。可以執行db.collectionName.getIndexes()來查看給定集合上的所有索引信息:
> db.foo.getIndexes() [ { "v" : 1, "key" : { "_id" : 1 }, "ns" : "test.foo", "name" : "_id_" }, { "v" : 1, "key" : { "y" : 1 }, "ns" : "test.foo", "name" : "y_1" }, { "v" : 1, "key" : { "x" : 1, "y" : 1 }, "ns" : "test.foo", "name" : "x_1_y_1" } ]
這里面最重要的字段是"key"和"name"。這里的鍵可以用在hint、max、min以及其他所有需要指定索引的地方。在這里,索引的順序很重要:{"x" : 1, "y" : 1}上的索引與{"y" : 1, "x" : 1}上的索引不同。對于很多的索引操作(比如dropIndex),這里的索引名稱都可以被當作標識符使用。但是這里不會指明索引是否是多鍵索引。
"v"字段只在內部使用,用于標識索引版本。如果你的索引不包含"v" : 1這樣的字段,說明你的索引是以一種效率比較低的舊方式存儲的。將MongoDB升級到至少2.0版本,刪除并重建這些索引,就可以把索引的存儲方式升級到新的格式了。
集合中的每一個索引都有一個名稱,用于唯一標識這個索引,也可以用于服務器端來刪除或者操作索引。索引名稱的默認形式是key name1_dir1_keyname2_dir2_..._keynameN_dirN,其中keynameX是索引的鍵,dirX是索引的方向(1或者-1)。如果索引中包含兩個以上的鍵,這種命名方式就顯得比較笨重了,好在可以在ensureIndex中指定索引的名稱:
> db.foo.ensureIndex({"a" : 1, "b" : 1, "c" : 1, ..., "z" : 1}, ... {"name" : "alphabet"})
索引名稱的長度是有限制的,所以新建復雜索引時可能需要自定義索引名稱。調用getLastError就可以知道索引是否成功創建,或者失敗的原因。
修改索引隨著應用不斷增長變化,你會發現數據或者查詢已經發生了改變,原來的索引也不那么好用了。這時可以使用dropIndex命令刪除不再需要的索引:
> db.people.dropIndex("x_1_y_1") { "nIndexesWas" : 3, "ok" : 1 }
用索引描述信息里"name"字段的值來指定需要刪除的索引。
新建索引是一件既費時又浪費資源的事情。默認情況下,MongoDB會盡可能快地創建索引,阻塞所有對數據庫的讀請求和寫請求,一直到索引創建完成。如果希望數據庫在創建索引的同時仍然能夠處理讀寫請求,可以在創建索引時指定background選項。這樣在創建索引時,如果有新的數據庫請求需要處理,創建索引的過程就會暫停一下,但是仍然會對應用程序性能有比較大的影響。后臺創建索引比前臺創建索引慢得多。
在已有的文檔上創建索引會比新創建索引再插入文檔快一點。
上一篇文章:MongoDB指南---12、使用explain()和hint()、何時不應該使用索引
下一篇文章:MongoDB指南---14、特殊的索引和集合:固定集合、TTL索引、全文本索引
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/19578.html
摘要:復合唯一索引也可以創建復合的唯一索引。中的稀疏索引與關系型數據庫中的稀疏索引是完全不同的概念。但是這里不會指明索引是否是多鍵索引。上一篇文章指南使用和何時不應該使用索引下一篇文章指南特殊的索引和集合固定集合索引全文本索引 上一篇文章:MongoDB指南---12、使用explain()和hint()、何時不應該使用索引下一篇文章:MongoDB指南---14、特殊的索引和集合:固定集合...
摘要:表示本次查詢使用了索引,具體來說,是使用了和上的索引,。建立索引時,或者是每執行次查詢之后,查詢優化器都會重新評估查詢計劃。上一篇文章指南使用復合索引操作符如何使用索引索引對象和數組索引基數下一篇文章指南索引類型 上一篇文章:MongoDB指南---11、使用復合索引、$操作符如何使用索引、索引對象和數組、索引基數下一篇文章:MongoDB指南---13、索引類型 使用explain...
摘要:表示本次查詢使用了索引,具體來說,是使用了和上的索引,。建立索引時,或者是每執行次查詢之后,查詢優化器都會重新評估查詢計劃。上一篇文章指南使用復合索引操作符如何使用索引索引對象和數組索引基數下一篇文章指南索引類型 上一篇文章:MongoDB指南---11、使用復合索引、$操作符如何使用索引、索引對象和數組、索引基數下一篇文章:MongoDB指南---13、索引類型 使用explain...
摘要:固定集合不能被分片。為固定集合指定文檔數量限制時,必須同時指定固定集合的大小。沒有索引的集合默認情況下,每個集合都有一個索引。 上一篇文章:MongoDB指南---13、索引類型、索引管理下一篇文章:MongoDB指南---15、特殊的索引和集合:地理空間索引、使用GridFS存儲文件 本章介紹MongoDB中一些特殊的集合和索引類型,包括: 用于類隊列數據的固定集合(capped...
摘要:固定集合不能被分片。為固定集合指定文檔數量限制時,必須同時指定固定集合的大小。沒有索引的集合默認情況下,每個集合都有一個索引。 上一篇文章:MongoDB指南---13、索引類型、索引管理下一篇文章:MongoDB指南---15、特殊的索引和集合:地理空間索引、使用GridFS存儲文件 本章介紹MongoDB中一些特殊的集合和索引類型,包括: 用于類隊列數據的固定集合(capped...
閱讀 2315·2021-09-22 15:27
閱讀 3170·2021-09-03 10:32
閱讀 3499·2021-09-01 11:38
閱讀 2499·2019-08-30 15:56
閱讀 2213·2019-08-30 13:01
閱讀 1537·2019-08-29 12:13
閱讀 1418·2019-08-26 13:33
閱讀 893·2019-08-26 13:30