您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)MongoDB如何查詢數(shù)組、內(nèi)嵌文檔和$where的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。
【查詢數(shù)組】
查詢數(shù)組很容易,對(duì)于數(shù)組,我們可以這樣理解:數(shù)組中每一個(gè)元素都是這個(gè)鍵值對(duì)鍵的一個(gè)有效值,如下面的例子:我們要查詢出售apple的水果店:
我們發(fā)現(xiàn)只要包含蘋果的數(shù)組都能被查詢出來(lái)。如果要通過(guò)多個(gè)元素來(lái)匹配數(shù)組,就需要條件操作符"$all",比如我們要查詢既賣apple又賣banana的水果店:
我們看,使用“$all”對(duì)數(shù)組內(nèi)元素的順序沒(méi)有要求,只要全部包含的數(shù)組都能查詢出來(lái)。數(shù)組查詢也可以使用精確匹配的方式,即查詢條件文檔中鍵值對(duì)的值也是數(shù)組,如:
如果是精確匹配的方式,MongoDB的處理方式是完全相同的匹配,即順序與數(shù)量都要一致,上述中第一條文檔和查詢條件的順序不一致,第三條文檔比查詢條件文檔多一個(gè)元素,都沒(méi)有被匹配成功!
對(duì)于數(shù)組的匹配,還有一種形式是精確指定數(shù)組中某個(gè)位置的元素匹配,我們前面提到,數(shù)組中的索引可以作為鍵使用,如我們要匹配水果店售第二種水果是orange 的水果店:
數(shù)組索引從0開(kāi)始,我們匹配第二種水果就用furits.1作為鍵。
"$size"條件操作符,可以用來(lái)查詢特定長(zhǎng)度的數(shù)組的,如我們要查詢賣3種水果的水果店:
但條件操作符"$size"不能和其他操作符連用如“$gt”等,這是這個(gè)操作符的一個(gè)缺陷。使用這個(gè)操作符我們只能精確查詢某個(gè)長(zhǎng)度的數(shù)組。如果實(shí)際中,在查詢某個(gè)數(shù)組時(shí),需要按其長(zhǎng)度范圍進(jìn)行查詢,這里推薦的做法是:在這個(gè)文檔中額外增加一個(gè)“size”鍵,專門記錄其中數(shù)組的大小,在對(duì)數(shù)組進(jìn)行"$push"操作同時(shí),將這個(gè)“size”鍵值加1。如下所示:
但這個(gè)方式和修改器"$addToSet"沒(méi)法配合使用,因?yàn)槟銦o(wú)法判斷這個(gè)元素是否添加到了數(shù)組中!
上篇提到了,find函數(shù)的第二個(gè)參數(shù)用于查詢返回哪些鍵,他還可以控制查詢返回?cái)?shù)組的一個(gè)子數(shù)組,如下例:我只想查詢水果店售賣說(shuō)過(guò)數(shù)組的前兩個(gè):
“$slice”也可以從后面截取,用復(fù)數(shù)即可,如-1表明截取最后一個(gè);還可以截取中間部分,如[2,3],即跳過(guò)前兩個(gè),截取3個(gè),如果剩余不足3個(gè),就全部返回!
如果第二個(gè)參數(shù)中有個(gè)鍵使用了條件操作符"$slice",則默認(rèn)查詢會(huì)返回所有的鍵,如果此時(shí)你要忽略哪些鍵,可以手動(dòng)指明!如:
【查詢內(nèi)嵌文檔】
查詢文檔有兩種方式,一種是完全匹查詢,另一種是針對(duì)鍵值對(duì)查詢!內(nèi)嵌文檔的完全匹配查詢和數(shù)組的完全匹配查詢一樣,內(nèi)嵌文檔內(nèi)鍵值對(duì)的數(shù)量,順序都必須一致才會(huì)匹配,如下例:
針對(duì)內(nèi)嵌文檔特定鍵值對(duì)的查詢是最常用的!通過(guò)點(diǎn)表示法來(lái)精確表示內(nèi)嵌文檔的鍵:
我們看,這樣查詢,所有有效文檔均被查詢到了!通過(guò)點(diǎn)表示法,可以表示深入到內(nèi)嵌文檔內(nèi)部的鍵!利用“點(diǎn)表示法”來(lái)查詢內(nèi)嵌文檔,這也約束了在插入文檔時(shí),任何鍵都不能包含“.” !!
當(dāng)內(nèi)嵌文檔變得復(fù)雜后,如鍵的值為內(nèi)嵌文檔的數(shù)組,這種內(nèi)嵌文檔的匹配需要一些技巧,如下例:
我們想要查詢?cè)u(píng)論中有叫“joe”并且其給出的分?jǐn)?shù)超過(guò)5分的blog文檔,但我們利用“點(diǎn)表示法”直接寫(xiě)是有問(wèn)題的,因?yàn)檫@條文檔有兩條評(píng)論,一條的作者名字叫“joe”但分?jǐn)?shù)只有3,一條作者名字叫“jimmy”,分?jǐn)?shù)卻給了5!也就是這條查詢條件和數(shù)組中不同的文檔進(jìn)行了匹配!這不是我們想要的,我們這里是要使用一組條件而不是單個(gè)指明每個(gè)鍵,使用條件操作符“$elemMatch”即可!他能將一組條件限定到數(shù)組中單條文檔的匹配上:
這樣做,結(jié)果是正確的!利用條件操作符“$elemMatch”可以組合一組條件,并且還能達(dá)到的“點(diǎn)表示法”的模糊查詢的效果!
【$where】
上面提到的所有的鍵值對(duì)的查詢方式,我們也可以看出,已經(jīng)很強(qiáng)大了!但如果實(shí)際中真的遇到一種情況無(wú)法用上述方式實(shí)現(xiàn)時(shí),不用慌,MongoDB為我們提供了終極武器:"$where",用他可以執(zhí)行任意JavaScript作為查詢的一部分!最典型的應(yīng)用:一個(gè)文檔,如果有兩個(gè)鍵的值相等,就選出來(lái),否則不選:
我們可以看出,使用"$where"其實(shí)就是寫(xiě)了一個(gè)javascript函數(shù),MongoDB在查詢時(shí),會(huì)將每個(gè)文檔轉(zhuǎn)換成一個(gè)javascript對(duì)象,然后扔到這個(gè)函數(shù)中去執(zhí)行,通過(guò)返回結(jié)果來(lái)判斷其是否匹配!在實(shí)際使用中,盡量避免使用”$where" 條件操作符,因?yàn)槠湫阅芎懿睿≡趫?zhí)行過(guò)程中,需要把每個(gè)檔案轉(zhuǎn)化為javascript對(duì)象!如果不可避免,則盡量這樣寫(xiě):find({”other“:”......“,......,“$where”:""}),即將"$where"放最后,作為結(jié)果調(diào)優(yōu),讓常規(guī)查詢作為前置過(guò)濾條件!這樣能減少一些性能損失!
我們這里還可以發(fā)現(xiàn),“$where”條件操作符也是作為外層文檔的鍵使用,昨天說(shuō)“$or”條件操作符是被作為外層文檔的鍵使用。其余目前遇到的條件操作符都是被作為內(nèi)層文檔的鍵使用!
感謝各位的閱讀!關(guān)于“MongoDB如何查詢數(shù)組、內(nèi)嵌文檔和$where”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。