Mongodb多鍵索引中索引邊界的混合問(wèn)題小結(jié)
學(xué)習(xí)mongodb,體會(huì)mongodb的每一個(gè)使用細(xì)節(jié),歡迎閱讀威贊的文章。這是威贊發(fā)布的第93篇mongodb技術(shù)文章,歡迎瀏覽本專欄威贊發(fā)布的其他文章。如果您認(rèn)為我的文章對(duì)您有幫助或者解決您的問(wèn)題,歡迎在文章下面點(diǎn)個(gè)贊,或者關(guān)注威贊。謝謝。
Mongodb為提高數(shù)組的查詢效率,針對(duì)數(shù)組構(gòu)建了多鍵索引。而Mongodb在應(yīng)用多鍵數(shù)組查詢時(shí),也通過(guò)構(gòu)建,減少數(shù)組查詢的數(shù)值范圍,來(lái)提高查詢性能。本文結(jié)合Mongodb官方文檔,闡述Mongodb在使用多鍵索引時(shí)的邊界優(yōu)化。
概述
索引邊界定義了索引值的區(qū)間段。Mongodb在查詢時(shí),用這個(gè)區(qū)間段來(lái)查詢索引中的數(shù)據(jù)。當(dāng)用戶針對(duì)索引字段指定多個(gè)查詢條件時(shí),mongdb嘗試合并這些查詢條件的區(qū)間范圍來(lái)計(jì)算出更小的范圍區(qū)間,來(lái)獲得更快的查詢速度并減少資源利用。
使用多鍵索引的邊界交集來(lái)查詢
邊界交集代表多個(gè)邊界相互重合的點(diǎn)。如有兩個(gè)區(qū)間[3, 無(wú)窮大]和[無(wú)窮小,6],這兩個(gè)區(qū)間的交集就是[3,6]。Mongodb將這種求交集的方式,應(yīng)用到數(shù)據(jù)查詢當(dāng)中。有一個(gè)構(gòu)建了索引的數(shù)組字段,當(dāng)使用$elemMatch指定多個(gè)查詢條件查詢數(shù)據(jù)時(shí),Mongodb會(huì)將查詢條件合并。下邊的例子,說(shuō)明了這種查詢優(yōu)化方法。
構(gòu)建結(jié)合students并插入數(shù)據(jù)
db.students.insertMany([ {_id: 1, name: 'Shawn', grades: [70,85]}, {_id: 2, name: 'Elena', grades: [92, 84]} ])
為數(shù)組創(chuàng)建多鍵索引
db.students.createIndex({grades: 1})
構(gòu)建查詢語(yǔ)句
db.students.find( { grades: { $elemMatch: { $gte: 90, $lte:99 } } } )
這個(gè)語(yǔ)句中,只要數(shù)組中任何一個(gè)數(shù)據(jù)符合大于等于90,小于等于99的數(shù)據(jù)。
單獨(dú)分析每個(gè)查詢條件,第一個(gè)邊界是[90,無(wú)窮大],第二個(gè)邊界是[無(wú)窮小,99],在使用$elemMatch時(shí),mongodb先計(jì)算兩個(gè)邊界的交集[90,99]
當(dāng)不使用$elemMatch時(shí),Mongodb不會(huì)先計(jì)算邊界的交集。
db.students.find( { grades: { $gte: 90, $lte:99 } } )
該查詢會(huì)查詢出滿足下面兩個(gè)條件的文檔
- 數(shù)組grades中至少有一個(gè)元素大于等于90
- 數(shù)組grades中至少有一個(gè)元素小于等于99
因?yàn)闆](méi)有使用$elemMatch, Mongodb不會(huì)計(jì)算邊界的交集。而是使用兩個(gè)邊界中的任何一個(gè)來(lái)查找,不能保證使用哪一個(gè)條件。
從解釋計(jì)劃當(dāng)中也能看出來(lái)兩者查詢數(shù)據(jù)范圍的不同
db.students.find( { grades: { $elemMatch: { $gte: 90, $lte:99 } } } ).explain() db.students.find( { grades: { $gte: 90, $lte:99 } } ).explain()
下面兩張圖片中,左邊使用了$elemMatch, 右側(cè)沒(méi)有使用
復(fù)合多鍵索引邊界混合
復(fù)合邊界集合了復(fù)合多鍵索引中的邊界。使用復(fù)合多鍵索引的多個(gè)字段邊界值,能夠減少查詢時(shí)間。Mongodb不需要單獨(dú)計(jì)算每個(gè)邊界的查詢結(jié)果。如符合索引{temperature: 1, humidity: 1}有下面的兩個(gè)邊界
- 溫度[80, 無(wú)窮大]
- 濕度[無(wú)窮小,20]
則計(jì)算出來(lái)的復(fù)合邊界就是
{ temperature: [80, 無(wú)窮大], humidity: [無(wú)窮小,20]}
如果mongodb不能將這兩個(gè)邊界混合,mongodb只能夠使用前面的字段索引來(lái)查詢數(shù)據(jù)。在這個(gè)例子中,前面的字段是temperature。下面的應(yīng)用,詳細(xì)描述了mongodb在復(fù)合多鍵索引中的邊界混合。
非數(shù)組字段和數(shù)組字段的邊界混合
這個(gè)例子展示了mongodb通過(guò)混合邊界來(lái)定義更高效的查詢約束提高性能
構(gòu)建survey集合并插入數(shù)據(jù)
db.survey.insertMany([ { _id: 1, item: "abc", ratings: [ 2, 5, 8 ] }, { _id: 2, item: "xyz", ratings: [ 5, 8 ] } ])
創(chuàng)建復(fù)合多鍵索引
db.survey.createIndex({item: 1, ratings: 1})
構(gòu)建查詢語(yǔ)句
db.survey.find({item: "abc", ratings: { $gte: 3}})
直接看執(zhí)行計(jì)劃,會(huì)更清楚一些
該查詢使用字段item和數(shù)組字段rating進(jìn)行查找。單獨(dú)來(lái)看么一個(gè)查詢條件
item字段值是“abc”, mongodb在執(zhí)行時(shí),轉(zhuǎn)換為邊界["abc", "abc"]
rating邊界是{$gte: 3},轉(zhuǎn)換為[3,無(wú)窮大]
mongodb將兩個(gè)邊界組合進(jìn)行查詢
非數(shù)組字段和多個(gè)數(shù)組字段的邊界混合
下面的例子展現(xiàn)了mongodb怎樣將非數(shù)組字段和多個(gè)數(shù)組字段的邊界混合
構(gòu)建集合survey2并插入數(shù)據(jù)
db.survey2.insertMany([ { _id: 1, item: "abc", ratings: [ { score: 2, by: "mn"}, { score: 9, by: "anon"}] }, { _id: 2, item: "xyz", ratings: [ { score: 5, by: "anon"}, { score: 7, by: "wv"}] } ])
為集合添加符合多鍵索引
db.survey2.createIndex({item: 1, "ratings.score": 1, "ratings.by": 1})
構(gòu)建查詢語(yǔ)句
db.surver2.find({item: "xyz", "ratings.score": { $lte: 5}, "ratings.by": "anon"})
單獨(dú)看每個(gè)查詢條件
- item字段的邊界 item: "xyz", 轉(zhuǎn)換為[["xyz", "xyz"]]
- score的邊界是{$lte:5},轉(zhuǎn)換為[無(wú)窮小, 5],
- by的邊界是 by: "anon",轉(zhuǎn)換為["anon", "anon"]
Mongodb 將item的邊界和ratings.score或ratings.by當(dāng)中的一個(gè)邊界混合,取決于查詢操作符和索引值。當(dāng)mongodb不能確認(rèn)使用哪個(gè)邊界來(lái)進(jìn)行混合。執(zhí)行計(jì)劃也無(wú)法確定使用哪個(gè)索引來(lái)進(jìn)行查詢。
為了保證mongodb能夠?qū)⑽臋n數(shù)組中的邊界混合,必須使用$elemMatch操作符
混合相同數(shù)組中多個(gè)字段的邊界
為了能夠混合相同數(shù)組中多個(gè)字段的索引邊界,必須滿足下面兩個(gè)條件
- 除了字段名稱以外,索引鍵必須在相同的路徑上
- 查詢語(yǔ)句必須使用$elemMatch查詢相同路徑上的值
在嵌入式文檔數(shù)組中,使用點(diǎn)操作符的字段名稱,如“a.b.c.d”, 就是字段d的字段路徑。為了能夠混合相同數(shù)組中的多個(gè)邊界,$elemMatch必須在這個(gè)路徑上,并且不包含字段本身。如“a.b.c”
在前面創(chuàng)建的集合survey2中添加索引
db.surver2.createIndex({"ratings.score": 1, "ratings.by": 1})
構(gòu)建查詢語(yǔ)句, 使用$elemMatch操作符查詢r(jià)atings字段,查詢出滿足兩個(gè)條件的數(shù)據(jù)。
db.surver2.find({ratings: {$elemMatch: {score: {$lte: 5}, by: "anon"}}})
看查詢計(jì)劃,能夠看到mongodb混合了兩個(gè)邊界為一個(gè)邊界
到此這篇關(guān)于Mongodb多鍵索引中索引邊界的混合的文章就介紹到這了,更多相關(guān)Mongodb多鍵索引邊界內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Ubuntu系統(tǒng)中安裝MongoDB及其啟動(dòng)命令mongod的教程
這篇文章主要介紹了Ubuntu系統(tǒng)中安裝MongoDB及其啟動(dòng)命令mongod的教程,包括設(shè)置MongoDB開(kāi)機(jī)啟動(dòng)的腳本示例,非常推薦,需要的朋友可以參考下2016-01-01MongoDB如何正確中斷正在創(chuàng)建的索引詳解
這篇文章主要給大家介紹了關(guān)于MongoDB如何正確中斷正在創(chuàng)建的索引的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12mongodb實(shí)現(xiàn)數(shù)組對(duì)象求和方法實(shí)例
這篇文章主要給大家介紹了關(guān)于mongodb實(shí)現(xiàn)數(shù)組對(duì)象求和的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01MongoDB學(xué)習(xí)筆記之分組(group)使用示例
這篇文章主要介紹了MongoDB學(xué)習(xí)筆記之分組(group)使用示例,本文直接給出一組測(cè)試數(shù)據(jù),然后練習(xí)分組的基本使用,需要的朋友可以參考下2015-07-07使用MongoDB進(jìn)行數(shù)據(jù)存儲(chǔ)的操作流程
在現(xiàn)代應(yīng)用開(kāi)發(fā)中,數(shù)據(jù)存儲(chǔ)是一個(gè)至關(guān)重要的部分,隨著數(shù)據(jù)量的增大和復(fù)雜性的增加,傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)有時(shí)難以應(yīng)對(duì)高并發(fā)和大數(shù)據(jù)量的處理需求,MongoDB作為一種高效的NoSQL數(shù)據(jù)庫(kù),逐漸成為了開(kāi)發(fā)者的首選,本文將介紹如何使用MongoDB進(jìn)行數(shù)據(jù)存儲(chǔ)2025-01-01