本章內容:
- 創建多鍵索引
- 指標界限
- 唯一多鍵索引
- 侷限性
- 例子
如果一個字段的保存值是數組,那麼,爲該字段創建索引時,MongoDB爲數組中的每個元素創建一個索引鍵。這些多鍵索引支持對數組字段的有效查詢。可以在數組上構造多鍵索引,數組中既可以保存標量值[1](例如字符串,數字)也可以是嵌套文檔。
[1]標量值是指既不是嵌入式文檔也不是數組的值。
一、創建多鍵索引
要創建多鍵索引,請使用db.collection.createIndex()方法:
db.coll.createIndex( { <field>: < 1 or -1 > } )
如果一個索引字段是數組,MongoDB會自動創建一個多鍵索引;而無需顯式指定多鍵類型。
在版本3.4中的更改:僅對於WiredTiger和In-Memory存儲引擎,
從MongoDB 3.4開始,對於使用MongoDB 3.4或更高版本創建的多鍵索引,MongoDB會跟蹤創建了多鍵索引的一個或多個字段。跟蹤此信息使MongoDB查詢引擎可以使用更嚴格的索引範圍。
二、指標界限
如果索引是多鍵,則索引範圍的計算需遵循特殊規則。有關多鍵索引範圍的詳細信息,請參見多鍵索引範圍。
三、唯一多鍵索引
對於唯一索引,唯一性約束作用跨越了集合中的多個獨立文檔,而不是單個文檔。
因爲唯一性約束適用於單獨的文檔,所以對於唯一的多鍵索引,文檔可能具有導致重複索引鍵值的數組元素,只要該文檔的索引鍵值不重複另一個文檔的索引鍵值即可。
有關更多信息,請參見跨單獨文檔的唯一約束。
四、侷限性
1.複合多鍵索引
對於複合多鍵索引,每個索引文檔最多可以有一個值是數組的索引字段,其。即:
- 如果文檔的一個以上的值是組數的字段要創建索引,則無法創建複合多鍵索引。例如,考慮一個包含以下文檔的集合:
{ _id: 1, a: [ 1, 2 ], b: [ 1, 2 ], category: "AB - both arrays" }
則不能在集合上創建複合多鍵索引{a:1,b:1},因爲a和b字段都是數組。
- 或者,如果已經存在複合多鍵索引,則不能插入違反此限制的文檔。
考慮一個包含以下文檔的集合:
{ _id: 1, a: [1, 2], b: 1, category: "A array" }
{ _id: 2, a: 1, b: [1, 2], category: "B array" }
允許使用複合多鍵索引{a:1,b:1},因爲對於每個文檔,複合多鍵索引只有一個字段是一個數組。即沒有文檔的a和b字段值同時是數組。
但是,在創建複合多鍵索引之後,如果您嘗試插入a和b字段均爲數組的文檔,則MongoDB將使插入失敗。
如果字段是數組,並且數組的字段是嵌入式的,則嵌入式的字段也可以創建複合索引。例如,考慮一個包含以下文檔的集合:
{ _id: 1, a: [ { x: 5, z: [ 1, 2 ] }, { z: [ 1, 2 ] } ] }
{ _id: 2, a: [ { x: 5 }, { z: 4 } ] }
您可以在{“ a.x”:1,“ a.z”:1}上創建複合索引。最多只能有一個索引字段可以是數組的限制也適用。
有關示例,請參見帶有嵌入式文檔的索引數組。
也可以看看
2.排序
由於MongoDB 3.6中對數組字段的排序行爲發生了變化,因此在對使用多鍵索引建立索引的數組上進行排序時,查詢計劃包括一個阻塞的SORT階段。新的排序行爲可能會對性能產生負面影響。
在阻塞式SORT中,必須在排序過程中使用所有輸入參數,然後才能產生輸出。在非阻塞或索引排序中,排序過程會掃描索引以按請求的順序產生結果。
3.分片鍵
您不能將多鍵索引指定爲分片鍵索引。
但是,如果分片鍵索引是複合索引的前綴,並且如果其他鍵(即不屬於分片鍵的鍵)是對數組建立的索引,則允許該複合索引成爲複合多鍵索引。複合多鍵索引可能會影響性能。
4.哈希索引
哈希索引不能爲多鍵。
5.覆蓋查詢
多鍵索引不能覆蓋對數組字段的查詢。
但是,從3.6開始,如果索引跟蹤哪個字段或哪些字段導致索引成爲多鍵,則多鍵索引可以覆蓋非數組字段的查詢。在MongoDB 3.4或更高版本中在MMAPv1 [#] _以外的存儲引擎上創建的多鍵索引會跟蹤此數據。
[2]從4.2版開始,MongoDB刪除了不贊成使用的MMAPv1存儲引擎。
6.整體查詢數組字段
當查詢過濾器指定整個數組的完全匹配項時,MongoDB可以使用多鍵索引查找查詢數組的第一個元素,但不能使用多鍵索引掃描來查找整個數組。相反,在使用多鍵索引查找數組的第一個元素之後,MongoDB檢索關聯的文檔並過濾其數組與查詢中的數組匹配的文檔。
例如,考慮包含以下文檔的庫存收集:
{ _id: 5, type: "food", item: "aaa", ratings: [ 5, 8, 9 ] }
{ _id: 6, type: "food", item: "bbb", ratings: [ 5, 9 ] }
{ _id: 7, type: "food", item: "ccc", ratings: [ 9, 5, 8 ] }
{ _id: 8, type: "food", item: "ddd", ratings: [ 9, 5 ] }
{ _id: 9, type: "food", item: "eee", ratings: [ 5, 9, 5 ] }
該集合在ratings 字段上具有多鍵索引:
db.inventory.createIndex( { ratings: 1 } )
以下查詢查找評級字段爲數組[5,9]的文檔:
db.inventory.find( { ratings: [ 5, 9 ] } )
MongoDB可以使用多鍵索引查找在ratings數組中具有5的文檔。然後,MongoDB檢索這些文檔並過濾其ratings 數組等於查詢數組[5、9]的文檔。
7.$ expr
$ expr不支持多鍵索引。
五、例子
1.基本數組索引
考慮包含以下文檔的survey集合:
{ _id: 1, item: "ABC", ratings: [ 2, 5, 9 ] }
在字段ratings上創建索引:
db.survey.createIndex( { ratings: 1 } )
由於ratings 字段包含一個數組,因此ratings 索引是多鍵的。該多鍵索引包含以下三個索引鍵,每個都指向同一文檔:
- 2,
- 5,
- 9。
2.帶有嵌入式文檔的索引數組
您可以在包含嵌套對象的數組字段上創建多鍵索引。
考慮具有以下格式文檔的inventory集合:
{
_id: 1,
item: "abc",
stock: [
{ size: "S", color: "red", quantity: 25 },
{ size: "S", color: "blue", quantity: 10 },
{ size: "M", color: "blue", quantity: 50 }
]
}
{
_id: 2,
item: "def",
stock: [
{ size: "S", color: "blue", quantity: 20 },
{ size: "M", color: "blue", quantity: 5 },
{ size: "M", color: "black", quantity: 10 },
{ size: "L", color: "red", quantity: 2 }
]
}
{
_id: 3,
item: "ijk",
stock: [
{ size: "M", color: "blue", quantity: 15 },
{ size: "L", color: "blue", quantity: 100 },
{ size: "L", color: "red", quantity: 25 }
]
}
...
以下操作在stock.size和stock.quantity字段上創建多鍵索引:
db.inventory.createIndex( { "stock.size": 1, "stock.quantity": 1 } )
複合多鍵索引可以支持包含索引字段的查詢,也支持僅包含索引前綴“ stock.size”的查詢,如以下示例所示:
db.inventory.find( { "stock.size": "M" } )
db.inventory.find( { "stock.size": "S", "stock.quantity": { $gt: 20 } } )
有關MongoDB如何組合多鍵索引範圍的詳細信息,請參閱多鍵索引範圍。有關複合索引和前綴的行爲的更多信息,請參見複合索引和前綴。
複合多鍵索引還可以支持排序操作,例如以下示例:
db.inventory.find( ).sort( { "stock.size": 1, "stock.quantity": 1 } )
db.inventory.find( { "stock.size": "M" } ).sort( { "stock.quantity": 1 } )
有關複合索引和排序操作的行爲的更多信息,請參見使用索引對查詢結果進行排序。
上一篇:複合索引