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