Mongodb數(shù)組字段索引之多鍵索引
學(xué)習(xí)mongodb,體會mongodb的每一個使用細節(jié),歡迎閱讀威贊的文章。這是威贊發(fā)布的第92篇mongodb技術(shù)文章,歡迎瀏覽本專欄威贊發(fā)布的其他文章。如果您認為我的文章對您有幫助或者解決您的問題,歡迎在文章下面點個贊,或者關(guān)注威贊。謝謝。
Mongodb字段允許包含字符,文檔,數(shù)組等各種各樣的類型。同樣Mongodb索引也可以支持字符,文檔,數(shù)組等類型。本文結(jié)合Mongodb官方文檔,介紹Mongodb數(shù)組類型數(shù)據(jù)的索引——多鍵索引。如果應(yīng)用經(jīng)常查詢數(shù)組字段,為該字段添加多鍵索引,能夠提高查詢效率,增加索引查詢覆蓋率,優(yōu)化數(shù)據(jù)庫查詢性能。
如在學(xué)生集合當(dāng)中,包含了存儲學(xué)生測驗成績的test_scores字段,這個學(xué)期的每一次測驗成績都會在這個數(shù)組當(dāng)中。老師需要查詢出至少5次測驗成績超過90分的學(xué)生 。這樣就可以在字段test_scores上添加索引來提高查詢效率。因為test_scores是數(shù)組類型,Mongodb自動為數(shù)組類型創(chuàng)建多鍵索引。
概述
多鍵索引,包含并排序了字段中的數(shù)組數(shù)據(jù)。多鍵索引,能夠改善數(shù)組字段的查詢性能。用戶不需要顯示的定義多鍵索引類型。當(dāng)Mongodb構(gòu)建索引時,看到該字段是數(shù)組字段,就會自動的創(chuàng)建多鍵索引。Mongodb可以為普通類型數(shù)據(jù)數(shù)組(如字符串?dāng)?shù)組,數(shù)字數(shù)組)和嵌入式文檔數(shù)據(jù)來構(gòu)建多鍵索引。如果一個數(shù)組包含相同值的多個元素,則Mongodb只會選擇這些元素中的一個來放入索引當(dāng)中。
下面的圖中描述了多鍵索引的結(jié)構(gòu)。有一個collection集合,字段addr是文檔類型的數(shù)組?,F(xiàn)在為addr數(shù)組中的zip字段建立索引。在索引當(dāng)中,數(shù)組元素的數(shù)值從小到大排列。

語法
使用下面的語句來創(chuàng)建多鍵索引
db.<collection>.createIndex({<arrayField>: <sortOrder>})使用和限制
索引邊界
在查詢中,邊界定義了索引掃描的各個部分。Mongodb在多鍵索引邊界計算上有特殊的規(guī)則,詳細查看文檔《Mongodb多鍵索引邊界》。
唯一多鍵索引
在唯一多鍵索引當(dāng)中,文檔的數(shù)組元素,只能包含集合中其他文檔數(shù)組中不存在的元素。
復(fù)合多鍵索引
在復(fù)合多鍵索引中,每一個文檔最多只能包含一個被索引的數(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)建索引。
如果一個復(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)建一個復(fù)合多鍵索引{scores_spring: 1, scores_fall:1},因為每一個文檔當(dāng)中,只有一個字段是數(shù)組索引,不包含這兩個字段同時是數(shù)組字段的文檔數(shù)據(jù)。該索引創(chuàng)建后,Mongodb不允許用戶插入兩個字段都是數(shù)據(jù)元素的文檔。
排序
基于數(shù)組字段的索引進行排序時,滿足下面兩個條件,才會使用索引排序,而不會在查詢中包含一個內(nèi)存排序。
- 所有排序字段的值包含在索引邊界最大最小值內(nèi)
- 任何一個與排序模版帶有相同前綴的多鍵索引都不能有邊界限制。這句話在文檔中很繞口。嘗試去理解一下。如前面提到的索引{scores_spring: 1, scores_fall:1}。當(dāng)某個查詢排序,使用{sort:{scores_spring:1}},這該排序字段是索引{scores_spring: 1, scores_fall:1}的索引前綴。在查詢當(dāng)中,不能對scores_spring做邊界限制,否者將使用內(nèi)存排序。
分片集合
多鍵索引的字段,不能作為分片鍵。但是,當(dāng)分片鍵是復(fù)合索引的前綴時,后續(xù)索引字段包含數(shù)組時,這個復(fù)合索引就會成為一個符合多鍵索引。
如下文檔, 集合中帶有索引{field2:1, field1: 1},當(dāng)使用field2字段作為分片集的關(guān)鍵字時,則field2既是分片關(guān)鍵字,也是復(fù)合索引的前綴。外國人寫的這些英語,還是很繞的,要理解一下。
{_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
})該索引是復(fù)合多鍵索引,但是能夠覆蓋在name字段的查詢
db.matches.find({
name: "joe"
}).explain()
使用數(shù)組作為查詢條件
當(dāng)查詢過濾器中,使用整個數(shù)組做為查詢條件時,Mongodb能夠使用多鍵索引,查詢數(shù)組過濾條件中的第一個數(shù)組元素,但不能使用多鍵索引去查詢整個數(shù)組。當(dāng)Mongodb使用多鍵索引查詢過濾數(shù)組中的第一個元素以后所查詢出來的文檔,Mongodb在內(nèi)存中會對這部分文檔進一步過濾,過濾出復(fù)合查詢條件中整個數(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表達式,不支持多鍵索引
應(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)常需要查詢出至少有一次測驗分數(shù)大于90的同學(xué),這可以向數(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 Windows安裝服務(wù)方法與注意事項
這篇文章主要介紹了MongoDB Windows安裝服務(wù)方法與注意事項的相關(guān)資料,MongoDB作為一個基于分布式文件存儲的數(shù)據(jù)庫,近兩年大受追捧。數(shù)據(jù)靈活的存取方式和高效的處理使得它廣泛用于互聯(lián)網(wǎng)應(yīng)用,需要的朋友可以參考下2016-12-12
解決MongoDB6.0報錯:"mongo"不是內(nèi)部或外部命令,也不是可運行的程序或批處理文件
這篇文章主要給大家介紹了關(guān)于解決MongoDB6.0報錯:"mongo"不是內(nèi)部或外部命令,也不是可運行的程序或批處理文件的相關(guān)資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下2023-05-05
記一次Mongodb中admin數(shù)據(jù)庫導(dǎo)致的事故
這篇文章主要給大家介紹了關(guān)于一次Mongodb中admin數(shù)據(jù)庫導(dǎo)致的事故的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-03-03
mongodb命令行連接及基礎(chǔ)命令總結(jié)大全
大家可能平時在開發(fā)過程中都使用客戶端工具來連接和查詢mongodb,但是一般生產(chǎn)當(dāng)中的數(shù)據(jù)庫是不允許本地客戶端連接的,下面這篇文章主要給大家介紹了關(guān)于mongodb命令行連接及基礎(chǔ)命令總結(jié)的相關(guān)資料,需要的朋友可以參考下2024-04-04

