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