MongoDB查詢(xún)與游標(biāo)之分布式文件存儲(chǔ)
一、查詢(xún)
1、find()基本用法
查詢(xún)就是返回集合中文檔的一個(gè)子集,子集的范圍從0個(gè)文檔到整個(gè)集合。要返回哪些文檔由find的第一個(gè)參數(shù)決定,該參數(shù)是一個(gè)用于指定查詢(xún)條件的文檔。
如果是空,則返回全部文檔。
當(dāng)向查詢(xún)文檔中添加鍵值對(duì)時(shí),就意味著限定了查詢(xún)條件。例如db.users.find({"name":"哪吒編程"})
可以在查詢(xún)文檔時(shí),傳入多個(gè)鍵值對(duì),相當(dāng)于關(guān)系型數(shù)據(jù)庫(kù)中的where ... and ...
。
2、指定要返回的鍵
有時(shí)候,只想查詢(xún)文檔中的部分鍵
> db.users.find({},{"id":1,"dept":1}) { "_id" : ObjectId("638b2822bb535f1c23f9b09a"), "id" : "1", "dept" : [ { "name" : "哪吒編程", "age" : 18, "address" : "大連" }, { "name" : "云韻", "age" : 19, "address" : "大連" }, { "name" : "美杜莎", "age" : 28, "address" : "北京" } ] } { "_id" : ObjectId("638b3944bb535f1c23f9b09b"), "id" : "1", "dept" : [ { "name" : "哪吒編程", "age" : 18, "address" : "大連" }, { "name" : "云韻", "age" : 19, "address" : "大連" }, { "name" : "美杜莎", "age" : 28, "address" : "北京" } ] } > db.users.find({},{"_id":0,"dept":1}) { "dept" : [ { "name" : "哪吒編程", "age" : 18, "address" : "大連" }, { "name" : "云韻", "age" : 19, "address" : "大連" }, { "name" : "美杜莎", "age" : 28, "address" : "北京" } ] } { "dept" : [ { "name" : "哪吒編程", "age" : 18, "address" : "大連" }, { "name" : "云韻", "age" : 19, "address" : "大連" }, { "name" : "美杜莎", "age" : 28, "address" : "北京" } ] }
3、查詢(xún)條件
$lt、$lte、$gt、$gte
都屬于比較運(yùn)算符,分別對(duì)應(yīng)<、<=、>、>=
。
可以將其組合使用以查找一個(gè)范圍內(nèi)的值。
> db.users.find({"dept.age":{"$gte":20,"$lte":30}})
4、or查詢(xún)
MongoDB中有兩種方式可以進(jìn)行or查詢(xún)。$in
可以用來(lái)查詢(xún)一個(gè)鍵的多個(gè)值。$or
則更通用一些,可以在多個(gè)鍵中查詢(xún)?nèi)我獾慕o定值。
> db.users.find({"id":{"$in":["1","3"]}}) { "_id" : ObjectId("638b2822bb535f1c23f9b09a"), "id" : "1", "dept" : [ { "name" : "哪吒編程", "age" : 18, "address" : "大連" }, { "name" : "云韻", "age" : 19, "address" : "大連" }, { "name" : "美杜莎", "age" : 28, "address" : "北京" } ] } { "_id" : ObjectId("638b3944bb535f1c23f9b09b"), "id" : "1", "dept" : [ { "name" : "哪吒編程", "age" : 18, "address" : "大連" }, { "name" : "云韻", "age" : 19, "address" : "大連" }, { "name" : "美杜莎", "age" : 28, "address" : "北京" } ] } { "_id" : ObjectId("638b4cacbb535f1c23f9b09c"), "id" : "3", "dept" : [ { "name" : "哪吒編程", "age" : 18, "address" : "大連" }, { "name" : "云韻", "age" : 19, "address" : "大連" }, { "name" : "美杜莎", "age" : 28, "address" : "北京" } ] } >
5、$not
$not
是一個(gè)元條件運(yùn)算符,可以用于任何其它條件之上。
二、特定類(lèi)型的查詢(xún)
1、null
null的行為有一些特別。它可以與自身匹配。
> db.users.find({"dept":null}) { "_id" : ObjectId("638b538682bdbdfa72665a11"), "id" : "1", "dept" : null }
2、正則表達(dá)式
"$regex"可以在查詢(xún)中為字符串的模式匹配提供正則表達(dá)式功能。正則表達(dá)式對(duì)于靈活的字符串匹配非常有用。
> db.users.find({"name":{"$regex":"哪吒"}})) { "_id" : ObjectId("638b549982bdbdfa72665a12"), "id" : "1", "name" : "哪吒編程", "age" : 18 } { "_id" : ObjectId("638b54cd82bdbdfa72665a15"), "id" : "1", "name" : "CSDN哪吒", "age" : 18 }
MongoDB會(huì)使用Perl兼容的正則表達(dá)式(PRCE)庫(kù)來(lái)對(duì)正則表達(dá)式進(jìn)行匹配。任何PCRE支持的正則表達(dá)式語(yǔ)法都能被MongoDB接受。
3、查詢(xún)數(shù)組
$all
可以通過(guò)多個(gè)元素匹配數(shù)組。
> db.workers.find({name:{$all:["哪吒編程","云韻"]}}) { "_id" : ObjectId("638b2154bb535f1c23f9b098"), "id" : "1", "name" : [ "哪吒編程", "云韻" ] } { "_id" : ObjectId("638b59fc82bdbdfa72665a16"), "id" : "1", "name" : [ "哪吒編程", "云韻", "美杜莎" ] } { "_id" : ObjectId("638b59fc82bdbdfa72665a17"), "id" : "2", "name" : [ "哪吒編程", "云韻", "納蘭嫣然" ] }
如果想在數(shù)組中查詢(xún)特定位置的元素,可以使用key.index
語(yǔ)法來(lái)指定下標(biāo):
> db.workers.find({"name.2":"美杜莎"}) { "_id" : ObjectId("638b59fc82bdbdfa72665a16"), "id" : "1", "name" : [ "哪吒編程", "云韻", "美杜莎" ] }
通過(guò)$size
指定要查找的數(shù)組的大?。?/p>
> db.workers.find({"name":{"$size":2}}) { "_id" : ObjectId("638b2154bb535f1c23f9b098"), "id" : "1", "name" : [ "哪吒編程", "云韻" ] }
4、數(shù)組與范圍查找的相互作用
先舉一個(gè)例子:
> db.student.find() { "_id" : ObjectId("638b6b8382bdbdfa72665a19"), "id" : "1", "name" : "哪吒編程", "age" : 18 } { "_id" : ObjectId("638b6b8482bdbdfa72665a1a"), "id" : "2", "name" : "云韻", "age" : 23 } { "_id" : ObjectId("638b6b8482bdbdfa72665a1b"), "id" : "3", "name" : "美杜莎", "age" : [ 15, 29 ] } { "_id" : ObjectId("638b6b8582bdbdfa72665a1c"), "id" : "3", "name" : "蕭炎", "age" : 38 } > db.student.find({"age":{"$gt":20,"$lt":28}}) { "_id" : ObjectId("638b6b8482bdbdfa72665a1a"), "id" : "2", "name" : "云韻", "age" : 23 } { "_id" : ObjectId("638b6b8482bdbdfa72665a1b"), "id" : "3", "name" : "美杜莎", "age" : [ 15, 29 ] }
和想象中的不太一樣啊,我的本意是查詢(xún)年齡在20~28之間的人,為什么呢?
文檔中的標(biāo)量(非數(shù)組元素)必須與查詢(xún)條件中的每一條子句相匹配。如果使用db.student.find({"age":{"$gt":20,"$lt":28}})
進(jìn)行查詢(xún),那么age必須介于20~28之間,然而,如果age是一個(gè)數(shù)組,那么當(dāng)age鍵中的某一個(gè)元素與查詢(xún)條件的任意一條語(yǔ)句相匹配時(shí),文檔也會(huì)被返回。(即15<28,29大于20),完美適配。
這樣就會(huì)使針對(duì)數(shù)組的范圍查詢(xún)失去了作用。
此時(shí),可以使用"$elemMatch"
強(qiáng)制MongoDB將這兩個(gè)子句與單個(gè)數(shù)組元素進(jìn)行比較。不過(guò),"$elemMatch"
不會(huì)匹配非數(shù)組元素。
-- 返回空 db.student.find({"age":{"$elemMatch":{"$gt":20,"$lt":28}}})
如果在查詢(xún)的字段上有索引,那么可以使用min和max將查詢(xún)條件遍歷的索引范圍限制為"$gt"
和"$lt"
的值。
db.student.find({"age":{"$gt":20,"$lt":28}}).min({"age":20}).max({"age":28})
現(xiàn)在,這條查詢(xún)語(yǔ)句只會(huì)遍歷值在20~28之間的索引。
三、游標(biāo)
數(shù)據(jù)庫(kù)會(huì)使用游標(biāo)返回find的執(zhí)行結(jié)果。游標(biāo)的客戶(hù)端實(shí)現(xiàn)通常能夠在很大程度上對(duì)查詢(xún)的最終輸出進(jìn)行控制。你可以限制結(jié)果的數(shù)量,跳過(guò)一些結(jié)果,按任意方向的任意鍵組合對(duì)結(jié)果進(jìn)行排序,以及執(zhí)行徐國(guó)其他功能強(qiáng)大的操作。
通過(guò)cursor.hasNext()
檢查是否還有其它結(jié)果,通過(guò)cursor.next()
用來(lái)對(duì)其進(jìn)行獲取。
調(diào)用find()時(shí),shell并不會(huì)立即查詢(xún)數(shù)據(jù)庫(kù),而是等到真正開(kāi)始請(qǐng)求結(jié)果時(shí)才發(fā)送查詢(xún),這樣可以在執(zhí)行之前給查詢(xún)附加額外的選項(xiàng)。cursor對(duì)象的大多數(shù)方法會(huì)返回游標(biāo)本身,這樣就可以按照任意順序?qū)⑦x項(xiàng)鏈接起來(lái)了。
在使用db.users.find();
查詢(xún)時(shí),實(shí)際上查詢(xún)并沒(méi)有真正執(zhí)行,只是在構(gòu)造查詢(xún),執(zhí)行cursor.hasNext()
,查詢(xún)才會(huì)發(fā)往服務(wù)器端。shell會(huì)立刻獲取前100個(gè)結(jié)果或者前4MB的數(shù)據(jù)(兩者之中的較小者),這樣下次調(diào)用next或者h(yuǎn)asNext時(shí)就不必再次連接服務(wù)器去獲取結(jié)果了。在客戶(hù)端遍歷完第一組結(jié)果后,shell會(huì)再次連接數(shù)據(jù)庫(kù),使用getMore請(qǐng)求更多的結(jié)果。getMore請(qǐng)求包含一個(gè)游標(biāo)的標(biāo)識(shí)符,它會(huì)向數(shù)據(jù)庫(kù)詢(xún)問(wèn)是否還有更多的結(jié)果,如果有則返回下一批結(jié)果。這個(gè)過(guò)程會(huì)一直持續(xù),直到游標(biāo)耗盡或者結(jié)果被全部返回。
四、游標(biāo)的生命周期
在服務(wù)器端,游標(biāo)會(huì)占用內(nèi)存和資源。一旦游標(biāo)遍歷完結(jié)果之后,或者客戶(hù)端發(fā)送一條消息要求終止,數(shù)據(jù)庫(kù)就可以釋放它正在使用的資源。
何時(shí)銷(xiāo)毀游標(biāo):
- 當(dāng)游標(biāo)遍歷完匹配的結(jié)果時(shí),它會(huì)消除自身;
- 當(dāng)游標(biāo)超出客戶(hù)端的作用域時(shí),驅(qū)動(dòng)程序會(huì)向數(shù)據(jù)庫(kù)發(fā)送一條特殊的消息,讓數(shù)據(jù)庫(kù)終止該游標(biāo);
- 如果10分鐘沒(méi)有被使用的話(huà),數(shù)據(jù)庫(kù)游標(biāo)也將自動(dòng)銷(xiāo)毀;
五、limit、skip、soat
1、常用的查詢(xún)選項(xiàng)
最常用的查詢(xún)選項(xiàng)是限制返回結(jié)果的數(shù)量、略過(guò)一定數(shù)量的結(jié)果以及排序。所有這些選項(xiàng)必須在查詢(xún)被發(fā)送到數(shù)據(jù)庫(kù)之前指定。
- limit:限制數(shù)量;
- skip:略過(guò);
- soat:排序,1是升序,-1是降序;
使用skip略過(guò)少量的文檔是可以的,但對(duì)于結(jié)果非常多的情況,skip會(huì)非常慢,因?yàn)橐紫日业奖宦赃^(guò)的結(jié)果,然后再丟棄這些數(shù)據(jù)。
2、使用skip進(jìn)行分頁(yè)
最簡(jiǎn)單的分頁(yè)方式是
> db.student.find().sort({"id":1}).limit(5) { "_id" : ObjectId("638b6b8382bdbdfa72665a19"), "id" : "1", "name" : "哪吒編程", "age" : 18 } { "_id" : ObjectId("638c6685e96330d24f819176"), "id" : "1", "name" : "哪吒編程", "age" : 18 } { "_id" : ObjectId("638c6685e96330d24f81917f"), "id" : "10", "name" : "云韻", "age" : 23 } { "_id" : ObjectId("638c6685e96330d24f819180"), "id" : "11", "name" : "美杜莎", "age" : 29 } { "_id" : ObjectId("638c6686e96330d24f819181"), "id" : "12", "name" : "蕭炎", "age" : 38 } > db.student.find().sort({"id":1}).skip(5).limit(5) { "_id" : ObjectId("638b6b8482bdbdfa72665a1a"), "id" : "2", "name" : "云韻", "age" : 23 } { "_id" : ObjectId("638c6685e96330d24f819177"), "id" : "2", "name" : "云韻", "age" : 23 } { "_id" : ObjectId("638b6b8582bdbdfa72665a1c"), "id" : "3", "name" : "蕭炎", "age" : 38 } { "_id" : ObjectId("638b6b8482bdbdfa72665a1b"), "id" : "3", "name" : "美杜莎", "age" : [ 15, 29 ] } { "_id" : ObjectId("638c6685e96330d24f819178"), "id" : "3", "name" : "美杜莎", "age" : 29 } > db.student.find().sort({"id":1}).skip(10).limit(5) { "_id" : ObjectId("638c6685e96330d24f819179"), "id" : "4", "name" : "蕭炎", "age" : 38 } { "_id" : ObjectId("638c6685e96330d24f81917a"), "id" : "5", "name" : "哪吒編程", "age" : 18 } { "_id" : ObjectId("638c6685e96330d24f81917b"), "id" : "6", "name" : "云韻", "age" : 23 } { "_id" : ObjectId("638c6685e96330d24f81917c"), "id" : "7", "name" : "美杜莎", "age" : 29 } { "_id" : ObjectId("638c6685e96330d24f81917d"), "id" : "8", "name" : "蕭炎", "age" : 38 } >
3、不用skip進(jìn)行分頁(yè)
可以通過(guò)以下方式:
到此這篇關(guān)于MongoDB查詢(xún)與游標(biāo)之徹底玩轉(zhuǎn)分布式文件存儲(chǔ)的文章就介紹到這了,更多相關(guān)MongoDB查詢(xún)與游標(biāo)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MongoDB高效讀寫(xiě)海量數(shù)據(jù)的方法
這篇文章介紹了MongoDB高效讀寫(xiě)海量數(shù)據(jù)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02教你使用mongoose實(shí)現(xiàn)多集合關(guān)聯(lián)查詢(xún)
這篇文章主要給大家介紹了關(guān)于如何使用mongoose實(shí)現(xiàn)多集合關(guān)聯(lián)查詢(xún)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-02-02MongoDB學(xué)習(xí)筆記之GridFS使用介紹
這篇文章主要介紹了MongoDB學(xué)習(xí)筆記之GridFS使用介紹,本文介紹了GridFS的作用、GridFS的一些使用方法、GridFS實(shí)現(xiàn)原理及注意事項(xiàng)等,需要的朋友可以參考下2015-07-07教你使用MongoDB導(dǎo)入導(dǎo)出備份數(shù)據(jù)
這篇文章主要介紹了教你使用MongoDB導(dǎo)入導(dǎo)出備份數(shù)據(jù)方法的相關(guān)資料,需要的朋友可以參考下2022-11-11Linux系統(tǒng)下安裝MongoDB的詳細(xì)方法圖文教程
這篇文章主要介紹了Linux系統(tǒng)下安裝MongoDB的詳細(xì)方法圖文教程,需要的朋友可以參考下2023-06-06修復(fù) Mac brew 安裝 mongodb 報(bào) Error: No available formula with th
最近在同事新的 Mac 電腦上安裝 mongodb,報(bào)了錯(cuò)誤 Error: No available formula with the name ‘mongodb’,今天就說(shuō)說(shuō)這個(gè)問(wèn)題如何解決,需要的朋友可以參考下2020-02-02MongoDB學(xué)習(xí)筆記之分組(group)使用示例
這篇文章主要介紹了MongoDB學(xué)習(xí)筆記之分組(group)使用示例,本文直接給出一組測(cè)試數(shù)據(jù),然后練習(xí)分組的基本使用,需要的朋友可以參考下2015-07-07mongodb 數(shù)據(jù)庫(kù)操作詳解--創(chuàng)建,切換,刪除
mongodb是nosql里面最像關(guān)系型數(shù)據(jù)庫(kù)的數(shù)據(jù)庫(kù)。單表操作,基本上可以和關(guān)系型數(shù)據(jù)庫(kù)差不多。mongodb比較易學(xué),易用,分幾期記錄一下,學(xué)習(xí)和使用mongodb過(guò)程。2014-07-07- 本文章先來(lái)給大家簡(jiǎn)單介紹關(guān)于MongoDB 數(shù)據(jù)分頁(yè)和排序 limit,skip用戶(hù)的一些基礎(chǔ)語(yǔ)句,然后用一個(gè)實(shí)例詳細(xì)介紹MongoDB 數(shù)據(jù)分頁(yè)和排序?qū)嵗椒ā?/div> 2014-08-08
Centos7 yum安裝mongodb實(shí)現(xiàn)步驟詳解
這篇文章主要介紹了Centos7 yum安裝mongodb實(shí)現(xiàn)步驟詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08最新評(píng)論