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