Mongodb數組字段索引之多鍵索引
學習mongodb,體會mongodb的每一個使用細節(jié),歡迎閱讀威贊的文章。這是威贊發(fā)布的第92篇mongodb技術文章,歡迎瀏覽本專欄威贊發(fā)布的其他文章。如果您認為我的文章對您有幫助或者解決您的問題,歡迎在文章下面點個贊,或者關注威贊。謝謝。
Mongodb字段允許包含字符,文檔,數組等各種各樣的類型。同樣Mongodb索引也可以支持字符,文檔,數組等類型。本文結合Mongodb官方文檔,介紹Mongodb數組類型數據的索引——多鍵索引。如果應用經常查詢數組字段,為該字段添加多鍵索引,能夠提高查詢效率,增加索引查詢覆蓋率,優(yōu)化數據庫查詢性能。
如在學生集合當中,包含了存儲學生測驗成績的test_scores字段,這個學期的每一次測驗成績都會在這個數組當中。老師需要查詢出至少5次測驗成績超過90分的學生 。這樣就可以在字段test_scores上添加索引來提高查詢效率。因為test_scores是數組類型,Mongodb自動為數組類型創(chuàng)建多鍵索引。
概述
多鍵索引,包含并排序了字段中的數組數據。多鍵索引,能夠改善數組字段的查詢性能。用戶不需要顯示的定義多鍵索引類型。當Mongodb構建索引時,看到該字段是數組字段,就會自動的創(chuàng)建多鍵索引。Mongodb可以為普通類型數據數組(如字符串數組,數字數組)和嵌入式文檔數據來構建多鍵索引。如果一個數組包含相同值的多個元素,則Mongodb只會選擇這些元素中的一個來放入索引當中。
下面的圖中描述了多鍵索引的結構。有一個collection集合,字段addr是文檔類型的數組?,F在為addr數組中的zip字段建立索引。在索引當中,數組元素的數值從小到大排列。
語法
使用下面的語句來創(chuàng)建多鍵索引
db.<collection>.createIndex({<arrayField>: <sortOrder>})
使用和限制
索引邊界
在查詢中,邊界定義了索引掃描的各個部分。Mongodb在多鍵索引邊界計算上有特殊的規(guī)則,詳細查看文檔《Mongodb多鍵索引邊界》。
唯一多鍵索引
在唯一多鍵索引當中,文檔的數組元素,只能包含集合中其他文檔數組中不存在的元素。
復合多鍵索引
在復合多鍵索引中,每一個文檔最多只能包含一個被索引的數組字段。
用戶不可以為多個數組創(chuàng)建索引。如在集合中包含了下面一個文檔數據
{_id: 1, scores_spring:[8, 6], scores_fall:[5,9]}
其中字段scores_spring和字段scores_fall是數組索引,用戶不能夠使用{scores_spring: 1, scores_fall:1}來創(chuàng)建索引。
如果一個復合索引已經存在,用戶也不能夠插入還是索引定義相違背的文檔數據。
如集合中包含文檔
{_id: 1, scores_spring:[8, 6], scores_fall:9} {_id: 2, scores_spring:6, scores_fall:[5, 7]}
用戶可以創(chuàng)建一個復合多鍵索引{scores_spring: 1, scores_fall:1},因為每一個文檔當中,只有一個字段是數組索引,不包含這兩個字段同時是數組字段的文檔數據。該索引創(chuàng)建后,Mongodb不允許用戶插入兩個字段都是數據元素的文檔。
排序
基于數組字段的索引進行排序時,滿足下面兩個條件,才會使用索引排序,而不會在查詢中包含一個內存排序。
- 所有排序字段的值包含在索引邊界最大最小值內
- 任何一個與排序模版帶有相同前綴的多鍵索引都不能有邊界限制。這句話在文檔中很繞口。嘗試去理解一下。如前面提到的索引{scores_spring: 1, scores_fall:1}。當某個查詢排序,使用{sort:{scores_spring:1}},這該排序字段是索引{scores_spring: 1, scores_fall:1}的索引前綴。在查詢當中,不能對scores_spring做邊界限制,否者將使用內存排序。
分片集合
多鍵索引的字段,不能作為分片鍵。但是,當分片鍵是復合索引的前綴時,后續(xù)索引字段包含數組時,這個復合索引就會成為一個符合多鍵索引。
如下文檔, 集合中帶有索引{field2:1, field1: 1},當使用field2字段作為分片集的關鍵字時,則field2既是分片關鍵字,也是復合索引的前綴。外國人寫的這些英語,還是很繞的,要理解一下。
{_id:1, field1: [2,8],field2: 'A'}
哈希索引
哈希索引,不能是多鍵索引
索引覆蓋查詢
多鍵索引不能覆蓋數組字段的查詢。但是,多鍵索引,能夠使用索引前綴,覆蓋非數組字段的查詢。如下面的一個使用案例。
在集合matches中插入文檔。
db.matches.insertMany([ { name: "joe", event: ["open", "tournament"]}, { name: "bill", event: ["match", "championship"]} ])
在name字段和event字段建立索引
db.matches.createIndex({ name: 1, event: 1 })
該索引是復合多鍵索引,但是能夠覆蓋在name字段的查詢
db.matches.find({ name: "joe" }).explain()
使用數組作為查詢條件
當查詢過濾器中,使用整個數組做為查詢條件時,Mongodb能夠使用多鍵索引,查詢數組過濾條件中的第一個數組元素,但不能使用多鍵索引去查詢整個數組。當Mongodb使用多鍵索引查詢過濾數組中的第一個元素以后所查詢出來的文檔,Mongodb在內存中會對這部分文檔進一步過濾,過濾出復合查詢條件中整個數組的文檔。
舉例說明一下這個過程。創(chuàng)建集合inventory并插入數據
db.inventory.insertMany([ { _id:5, type: "food", item:"apple", ratings: [ 5, 8, 9 ] }, { _id:6, type: "food", item:"banana", ratings: [ 5, 9 ] }, { _id:7, type: "food", item:"grapes", ratings: [ 9, 5, 8 ] }, { _id:8, type: "food", item:"orange", ratings: [ 5, 9, 5 ] }, { _id:9, type: "food", item:"pear", ratings: [ 9, 5 ] } ])
在數組ratings建立多鍵索引
db.inventory.createIndex({ratings: 1})
構建一個使用數組作為過濾器的查詢語句
db.inventory.find({ ratings: [5, 9] })
在查詢計劃中,能夠看出,mongodb先使用5通過多鍵索引,查詢出所有包含元素5的文檔,然后在內存中過濾出包含整個數組[5,9]的文檔數據
$expr
$expr表達式,不支持多鍵索引
應用
為數值數組添加索引
創(chuàng)建students集合,并插入數據。其中 test_scores是數值類型的數組。
db.students.insertMany([ {name: 'Andre Robinson', test_scores: [88, 97]}, {name: 'Alice Martin', test_scores: [62, 73]}, {name: 'Bob Smith', test_scores: [92, 89]} ])
用戶經常需要查詢出至少有一次測驗分數大于90的同學,這可以向數組字段添加索引來提高性能
db.students.createIndex({test_scores: 1})
因為字段test_scores是數組類型,所以Mongodb自動為該字段創(chuàng)建了多鍵索引。該索引中包含了字段test_scores的所有值,并按照從小到大排列,[62, 73, 88, 89, 92, 97].該索引支持在字段test_scores上的查詢
如
db.students.find({ test_scores: { $elemMatch: { $gte: 90 } } })
為文檔數組添加索引
構建inventory集合并插入數據
db.inventory.insertMany([ { item: "t-shirt", stock: [ { size: "S", quantity: 8 }, { size: "L", quantity: 10 } ] }, { item: "sweater", stock: [ { size: "S", quantity: 4 }, { size: "M", quantity: 7 } ] }, { item: "vest", stock: [ { size: "S", quantity: 6 }, { size: "L", quantity: 1 } ] } ])
用戶需要在庫存低于5的時候,下訂單來補貨。為了查找出哪些需要補貨,需要構建語句,查出來stock數組中,數量quantity少于5的記錄。為了提高性能,用戶需要在字段stock.quantity上添加索引。
db.inventory.createIndex({'stock.quantity': 1})
因為stock是包含文檔的數組,索引Mongodb將這個索引存儲為多鍵索引。該索引將字段stock.quantity所有值按照從小到大排列[1,4,6,7,8,10]
構建語句,查詢出少于5的數據
db.inventory.find({'stock.quantity': { $lt: 5 }})
查詢數據,按照庫存的倒序排列
db.inventory.find().sort({'stock.quantity': -1})
到此這篇關于Mongodb數組字段索引之多鍵索引的文章就介紹到這了,更多相關Mongodb多鍵索引內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
MongoDB模糊查詢操作案例詳解(類關系型數據庫的 like 和 not like)
這篇文章主要介紹了MongoDB的模糊查詢操作(類關系型數據庫的 like 和 not like) ,本文通過代碼案例分析給大家介紹的非常詳細,具有一定的參考借鑒價值,,需要的朋友可以參考下2019-07-07centos離線安裝mongodb-database-tools方法詳解
這篇文章主要介紹了centos離線安裝mongodb-database-tools方法詳解的相關資料,需要的朋友可以參考下2022-11-11mongodb使用docker搭建replicaSet集群與變更監(jiān)聽(最新推薦)
replicaSet和cluster從部署難度相比,replicaSet要簡單許多。如果所存儲的數據量規(guī)模不算太大的情況下,那么使用replicaSet方式部署mongodb是一個不錯的選擇,這篇文章主要介紹了mongodb使用docker搭建replicaSet集群與變更監(jiān)聽,需要的朋友可以參考下2023-03-03