MongoDB學習筆記三:查詢

MongoDB中使用find來進行查詢。查詢就是返回一個集合中文檔的子集,子集合的范圍從0個文檔到整個集合。find的第一個參數決定了要返回哪些文檔,其形式也是一個文檔,說明要執行的查詢細節。
空的查詢文檔{}會匹配集合的全部內容。要是不指定查詢文檔,默認就是{}。
例如:
> db.c.find()
將返回集合c中的所有內容。
查找所有"age"的值為27的文檔:
> db.users.find({"age" : 27})
查找所有值為"joe"的"username"鍵:
> db.users.find({"username" : "joe"})
可以通過向查詢文檔加入多個鍵/值對的方式來將多個查詢條件組合在一起。例如,查詢所有用戶名為"joe"且年齡為27歲的用戶:
> db.users.find({"username" : "joe", "age" : 27})
『指定返回的鍵』
有時并不需要將文檔中的所有鍵/值對都返回。遇到這種情況,可以通過find(或者findOne)的第二個參數來指定想要的鍵。
例如,如果只對用戶集合的"username"和"email"鍵感興趣,可以使用如下查詢返回這些鍵:
> db.users.find({}, {"username" : 1, "email" : 1})
也可以用第二個參數來剔除查詢結果中的某個鍵/值對。例如,文檔中有很多鍵,但是不希望結果中含有"fatal_weakness"鍵:
> db.users.find({}, {"fatal_weakness" : 0})
也可以用來防止返回"_id":
> db.users.find({}, {"username" : 1, "_id" : 0})
查詢條件
比較操作符"$lt"、"$lte"、"$gt"、"$gte"分別對應<、<=、>、>=。
例:查詢在18~30歲(含)的用戶:
> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
查詢在2007年1月1日前注冊的人:
> start = new Date("01/01/2007")
> db.users.find({"registered" : {"$lt" : start}})
使用條件操作符"$ne"表示"不相等"。
例:查詢所有名字不為"joe"的用戶:
> db.users.find({"username" : {"$ne" : "joe"}})
"$ne"能用于所有類型的數據。
『OR查詢』
MongoDB中有兩種方式進行OR查詢:"$in"用來查詢一個鍵的多個值;"$or"用來完成多個鍵值的任意給定值。
對于單一鍵要是有多個值與其匹配的話,就要用"$in"加一個條件數組。例如,抽獎活動的中獎號碼是725、542和390.要找出全部這些中獎數據,可以構建如下查詢:
> db.raffle.find({"ticket_no" : {"$in" : [725, 542, 390]}})
"$in"可以指定不同的類型的條件和值。例如,在逐步將用戶名的ID號遷移成用戶名的過程中,要做兼顧二者的查詢:
> db.users.find({"user_id" : {"$in" : [12345, "joe"]}})
這會匹配"user_id"等于12345的文檔,也會匹配"user_id"等于"joe"的文檔。
如果"$in"對應的數組只有一個值,那么和直接匹配這個值效果是一樣的。例如,{ticket_no : {$in : [725]}}等價于{ticket_no : {$in : 725}}。
與"$in"相對的是"$nin",將返回與數組中所有條件都不匹配的文檔。要是想返回所有沒有中獎的人,就可以用如下方法進行查詢:
> db.raffle.find({"ticket_no" : {"$nin" : [725, 542, 390]}})
查詢將會返回沒有那些號碼的人。
"$or"接受一個包含所有可能條件的數組作為參數。例:找"ticket_no"為725或者"winner"為true的文檔:
> db.raffle.find({"$or" : [{"ticket_no" : 725}, {"winner" : true}]})
"$or"可以含有其他條件句。例如,如果想要將"ticket_no"與那三個值匹配上,外加"winner"鍵,就可以這么做:
> db.raffle.find({"$or" : [{"ticket_no" : {"$in" : [725, 542, 390]}}, {"winner" : true}]})
『$not』
"$not"是元條件句,即可以用在任何其他條件之上。例:對于取模運算符"$mod"來說。"$mod"會將查詢得知除以第一個給定值,若余數等于第二個給定值則返回該結果:
> db.users.find({"id_num" : {"$mod" : [5, 1]}})
上面的結果會返回"id_num"值為1、6/11/16等的用戶。如果要返回"id_num"為2、3、4、5、7、8、9、10、12等的用戶,則應使用"$not":
> db.users.find("id_num" : {"$not" : {"$mod" : [5, 1]}})
!"$not"與正則表達式聯合使用的時候極為有用,用來查找那些與特定模式不符的文檔。
『條件句的規則』
條件句是內層文檔的鍵,而修改器則是外層文檔的鍵。
一個鍵可以由多個條件,但是一個鍵不能對應多個更新修改器。
『特定于類型的查詢』
"null"不僅能匹配自身,而且能匹配"不存在的"。
如果僅僅想要匹配鍵值為null的文檔,既要檢查該鍵的值是否為null,還要通過"$exists"條件判定值已經已存在:
> db.c.find({"z" : {"$in" : [null], "$exists" : true}})
『正則表達式』
例:想要查找所有名為Joe或者joe的用戶,就可以使用正則表達式執行忽略大小寫的匹配:
> db.users.find({"name" : /joe/i})
匹配各種大小寫的joe以及joey:
> db.users.find({"name" : /joe?/i})
MongoDB使用Perl兼容的正則表達式(PCRE)庫來匹配正則表達式,PCRE支持的正則表達式語法都能被MongoDB所接受。
MongoDB可以為前綴正則表達式(比如/^joey/)查詢創建索引,所以這種類型的查詢會非常高效。
正則表達式也可以匹配自身。雖然幾乎沒有人直接將正則表達式插入到數據庫中,但是萬一這么做了,也是可以用自身匹配的:
> db.foo.insert({"bar" : /baz/})
> db.foo.find({"bar" : /baz/})
查詢數組
數組絕大多數情況下可以這樣理解:每一個元素都是整個鍵的值。例如,如果數組是一個水果清單,比如下面這樣:
> db.food.insert({"fruit" : ["apple", "banana", "peach"]})
下面的查詢:
> db.food.find({"fruit" : "banana"})
會成功匹配該文檔。
①$all
通過多個元素來匹配數組,使用"$all"。
例如,假設創建包含3個元素的如下集合:
> db.food.insert({"_id" : 1, "fruit" : ["apple", "banana", "peach"]})
> db.food.insert({"_id" : 2, "fruit" : ["apple", "kumquat", "orange"]})
> db.food.insert({"_id" : 3, "fruit" : ["cherry", "banana", "apple"]})
要找到既有"apple"又有"banana"的文檔,就得用"$all"來查詢:
> db.food.find(fruit : {$all : ["apple", "banana"]})
db.food.insert({"_id" : 1, "fruit" : ["apple", "banana", "peach"]})
db.food.insert({"_id" : 3, "fruit" : ["cherry", "banana", "apple"]})
要是想查詢數組指定位置的元素,則需使用key.index語法指定下標,如:
> db.food.find({"fruit.2" : "peach"})
數組下標從0開始,上面的表達式會用數組的第3個元素和"peach"匹配。
②$size
"$size"用于查詢指定長度的數組。例:
> db.food.find({"fruit" : {"$size" : 3}})
③$slice操作符
find的第二個參數是可選的,可以指定返回那些鍵。"$slice"返回數組的一個子集合。
例如,假設現在有一個博客文章的文檔,要想反悔前10條評論,可以:
> db.blog.posts.findOne(criteria, {"comments" : {"$slice" : 10}})
也可以返回后10條評論,只要-10就可以了:
> db.blog.posts.findOne(criteria, {"comments" : {"$slice" : -10}})
"$slice"也可以接受偏移值和要返回的元素數量,來返回中間的結果:
> db.blog.posts.findOne(criteria, {"comments" : {"$slice" : [23, 10]}})
這個操作會跳過前23個元素,返回第24個~第33個元素。如果數組不夠33個元素,則返回第23個元素后面的所有元素。
使用"$slice"默認返回文檔中的所有鍵。
『查詢內嵌文檔』
有兩種方法查詢內嵌文檔:查詢整個文檔,或者只針對鍵/值對進行查詢。
例,對于如下文檔:
{
"name" : {
"first" : "Joe"
"last" : "Schmoe"
},
"age" : 45
}
要查詢姓名為Joe Schmoe的人可以這樣:
> db.people.find({"name" : {"first" : "Joe", "last" : "Schmoe"}})
可以使用點表示法查詢內嵌的鍵:
> db.people.find({"name.first" : {"first" : "Joe", "last" : "Schmoe"}})
例:假設有博客文章若干,要找到由Joe發表的5分以上的評論。要正確地指定一組條件,而不用指定每個鍵,要使用"$elemMatch"。這種模糊的命名條件句能用來部分指定匹配數組中的單個內嵌文檔的限定條件:
> db.blog.find({"comments" : {"$elemMatch" : {"author" : "joe", "score" : {"$gte" : 5}}}})
"$elemMatch"將限定條件進行分組,僅當需要對一個內嵌文檔的多個鍵操作時才會用到。
『$where查詢』
使用"$where"可以執行任意JavaScript作為查詢的一部分。
最典型的應用就是比較文檔中的兩個鍵的值是否相等。例如,有個條目列表,如果其中的兩個值相等則返回文檔。如下示例:
> db.foo.insert({"apple" : 1, "banana" : 6, "peach" : 3})
> db.foo.insert({"apple" : 8, "spinach" : 4, "watermelon" : 4})
第二個文檔中,"spinach"和"watermelon"的值相同,所以需要返回該文檔。MongoDB似乎用于不會提供一個$條件符來做這個,所以只能用"$where"自居借助JavaScript來完成:
> db.foo.find({"$where" : function() {
for(var current in this) {
for(var other in this) {
if(current != other && this[current] == this[other]) {
return true;}
}
}
return false;
}});
如果函數返回true,文檔就作為結果的一部分被返回;如果為false,則不然。
也可以用一個字符串來指定"$where"查詢。下面兩種表達式是完全等價的:
> db.foo.find({"$where" : "this.x + this.y == 10"})
> db.foo.find({"$where" : "function() { return this.x + this.y == 10; }"})
"$where"在速度上比常規查詢慢很多。
『游標』
要想從shell中創建一個游標,首先要對集合填充一些文檔,然后對其執行查詢,并將結果分配給一個局部變量(用var生命的變量就是局部變量)。這里,先創建一個簡單的幾何,而后做個查詢,并用cursor變量保存結果:
> for(i=0; i<100; i++) {
db.collection.insert({x : i});
}
> var cursor = db.collection.find();
要跌待結果,可以使用游標的next方法。也可以使用hasNext來查看有沒有其他結果。典型的結果遍歷如下:
> while (cursor.hasNext()) {
obj = cursor.next();
// do stuff
}
cursor.hasNext()檢查是否有后續結果存在,然后用cursor.next()將其獲得。
游標類還實現了迭代器接口,可以在foreach循環中使用。
> var cursor = db.people.find()
> cursor.forEach(function(x) {
print(x.name);
});
『limit、skip和sort』
要限制結果數量,可在find后使用limit函數。例如,只返回3個結果,可以這樣:
> db.c.find().limit(3)
忽略掉前3個匹配的文檔,然后返回余下的文檔:
> db.c.find().skip(3)
sort用一個對象作為參數:一組鍵/值對,鍵對應文檔的別名,值代表排序的方向。排序方向可以是1(升序)或者-1(降序)。如果指定了多個鍵,則按照多個鍵的順序逐個排序。例如,要按照"username"升序及"age"降序排序,可以這樣寫:
> db.c.find().sort({username : 1, age : -1})
這3個方法可以組合使用。這對于分頁非常有用。例如,你有個在線商店,有人想搜索mp3。若是想每頁返回50個結果,而且按照價格從高到低排序,可以這樣寫:
> db.stock.find({"desc" : "mp3"}).limit(50).sort({"price" : -1})
點擊“下一頁”可以看到更多的結果,通過skip也可以非常簡單地實現,只需要略過前50個結果就好了(已經在第一頁顯示了):
> db.stock.find({"desc" : "mp3"}).limit(50).skip(50).sort({"price" : -1})
比較順序:MongoDB處理不同類型的數據有一個順序:
(1)最小值
(2)null
(3)數字(整型、長整型、雙精度)
(4)字符串
(5)對象/文檔
(6)數組
(7)二進制數據
(8)對象ID
(9)布爾型
(10)日期型
(11)時間戳
(12)正則表達式
(13)最大值
『避免使用skip略過大量結果』
1.不用skip的結果進行分頁
最簡單的分頁方法是用limit返回結果的第一頁,然后將每個后續頁面作為相對于開始的偏移量返回。
> // do not use: slow for large skips
> var page1 = db.foo.find(criteria).limit(100)
> var page2 = db.foo.find(criteris).skip(100).limit(100)
> var page3 = db.foo.find(criteris).skip(200).limit(100)
...
然而,一般來講可以找到一種方法實現不用skip的分頁,這取決于查詢本身。例如,要按照"date"降序顯示文檔,可以用如下方式獲取結果的第一頁:
> var page1 = db.foo.find().sort({"date" : -1}).limit(100)
然后,可以利用最后一個文檔中"date"的值作為查詢條件,來獲取下一頁:
var latest = null;

// dispaly first page
while (page1.hasNext()) {
latest = page1.next();
display(latest);
}

// get next page
vat page2 = db.foo.find({"date" : {"$gt" : latest.date}});
page2.sort({"date" : -1}).limit(100);
這樣查詢中就沒有skip了。
2.隨機選取文檔
例:想隨機找一個加州的水暖工,可以對"profession"、"state"和"random"建立索引:
> db.people.ensureIndex({"profession" : 1, "state" : 1, "random" : 1})
這樣就能很快得出一個結果了。
『高級查詢選項』
查詢分為包裝的和普通的兩類。
普通的查詢:
> var cursor = db.foo.find({"foo" : "bar"})
有幾個選項用于包裝查詢。例如,假設我們執行一個排序:
> var cursor = db.foo.find({"foo" : "bar"}).sort({"x" : 1})
實際情況不是將{"foo" : "bar"}作為查詢直接發送給數據庫,而是將查詢包裝在一個更大的文檔中。shell會把查詢從{"foo" : "bar"}轉換成{"$query" : {"foo" : "bar"}}, "$orderby" : {"x" : 1}
絕大多數驅動程序有些輔助措施向查詢添加各種選項。舉例:
· $maxscan : integer
指定查詢最多掃描的文檔數量
· $min : document
查詢的開始條件
· $max : document
查詢的結束條件
· $hint : document
指定服務器使用哪個索引進行查詢
· $explain : boolean
獲取查詢執行的細節(用到的索引、結果數量、耗時等),而并非真正執行查詢。
· $snapshot : boolean
確保查詢的結果是在查詢執行那一刻的一致快照
獲取一致結果:當使用了"$snapshot"選項,查詢就是針對不變的集合視圖運行的。
游標內幕:客戶端游標以及客戶端游標表示的數據庫游標。

?

轉載于:https://www.cnblogs.com/answernotfound/p/mongodbnote3.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/272544.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/272544.shtml
英文地址,請注明出處:http://en.pswp.cn/news/272544.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

計算機基礎 課程簡介,課程簡介及計算機基礎知識課件.ppt

文檔介紹&#xff1a;C語言程序設計主講教師:王偉****************qtc.課程簡介:課程類別:專業計劃學時:644學時/周16周課程學分:4課程學****結束后要求達到的要求掌握C語言的基礎知識能在TurboC和VC的環境中設計程序實現解決小規模問題上課要求:不遲到、不早退,有事和身體原因…

困擾程序員的30種軟件開發問題,你是否時曾相識?

我相信許多web開發人員和軟件工程師在編程中都會遇到困難&#xff0c;而事后回想起來&#xff0c;還會覺得很好笑。1、我不知道該刪掉還是重寫回歸曾經寫的源代碼&#xff0c;總有一種想要重新返工的沖動&#xff0c;邏輯性差&#xff0c;冗余代碼多&#xff0c;讓人難以理解。…

SQl 作業方面(轉)

企業管理器 --管理 --SQL Server代理 --右鍵作業 --新建作業 --"常規"項中輸入作業名稱 --"步驟"項 --新建 --"步驟名"中輸入步驟名 --"類型"中選擇"Transact-SQL 腳本(TSQL)" --"數據庫"選擇執行命令的數據庫 --…

燕山大學計算機專業研究生怎么樣,求助大家!重慶郵電大學計算機專業的研究生值得一讀嗎?...

求助大家&#xff01;重慶郵電大學計算機專業的研究生值得一讀嗎&#xff1f; 魅力前線 yanshandaxue2008-4-22 1 / 13 aiyabukaoyan2008-4-22 16:28求助大家&#xff01;重慶郵電大學計算機專業的研究生值得一讀嗎&#xff1f; 云南大學 yanshandaxue2008-4-22 1 / 13 每天一點…

有哪些新手程序員不知道的小技巧?

1.重構是程序員的主力技能。2.工作日志能提升腦容量。3.先用profiler調查&#xff0c;才有臉談優化。4.注釋貴精不貴多。杜絕大姨媽般的“例注”。漫山遍野的碎碎念注釋&#xff0c;實際就是背景噪音。5.普通程序員google超級程序員。6.單元測試總是合算的。7.不要先寫框架再寫…

Bezier曲線

1. 學習網址 http://give.zju.edu.cn/cgcourse/new/book/8.2.htm轉載于:https://www.cnblogs.com/icmzn/p/5082154.html

絕地求生登錄計算機需要授權,絕地求生國服第三方授權登錄異常解決方法 絕地求生國服授權登錄錯誤怎么辦...

近日&#xff0c;Steam第三方授權登錄發生異常&#xff0c;導致所有需要Steam賬號綁定登錄的網站都出現登錄錯誤&#xff0c;下面就為大家帶來絕地求生國服第三方授權登錄異常解決方法。絕地求生國服第三方授權登錄異常解決方法老兵登機活動綁定公告親愛的老兵們&#xff1a;今…

USE平臺構件屬性無法顯示的一種解決辦法

國開行USE平臺&#xff0c;構件屬性無法完整顯示&#xff0c;是因為ADSafe&#xff08;凈網大師&#xff09;的攔截。關閉掉凈網大師就OK了。轉載于:https://www.cnblogs.com/helloIT/articles/5082188.html

SQL Server索引怎么用

什么是索引拿漢語字典的目錄頁&#xff08;索引&#xff09;打比方&#xff1a;正如漢語字典中的漢字按頁存放一樣&#xff0c;SQL Server中的數據記錄也是按頁存放的&#xff0c;每頁容量一般為4K 。為了加快查找的速度&#xff0c;漢語字&#xff08;詞&#xff09;典一般都有…

EF 實現自定義數據庫字符串

1、EF模板生成繼承DbContext的類文件重新建一個部分類文件避免每次生成實體都會覆蓋掉。2、重新構造調用數據庫連接字符串的函數VS模板生成示例&#xff1a;public Test_DBEntities(): base("nameTest_DBEntities"){} 重寫函數public Test_DBEntities(string conn…

函數及自定義函數

SQL Server中的函數&#xff08;字符串函數&#xff0c;日期函數&#xff0c;數學函數&#xff0c;系統函數&#xff09; 字符串函數&#xff08;用于控制返回給用戶的字符串&#xff09; 1.charindex 尋找一個指定的字符串在另一個字符串中的起始位置 select charindex (JB…

鏈表定義、鏈表的插入、鏈表的刪除、鏈表的查找

鏈表的定義 鏈表是一種常見的重要的數據結構。它是動態地進行存儲分配的一種結構。它可以根據需要開辟內存單元。鏈表有一個“頭指針”變量&#xff0c;以head表示&#xff0c;它存放一個地址。該地址指向一個元素。鏈表中每一個元素稱為“結點”&#xff0c;每個結點都應包括兩…

原神服務器維護后抽獎池會更新嗎,原神:武器池改動,玩家的訴求再次得到反饋!PS端將與官服互通!...

大伙直播都看了嗎&#xff1f;反正我看完了。現在滿腦子都是大偉哥的嗯典。這好嗎&#xff1f;這不好。但是沒有關系&#xff0c;內容還是有的。首先&#xff0c;劇情上的雷神確立了&#xff0c;就是這位大姐。(好像有什么鋒利的東西懸在了我的頭頂&#xff0c;不過這上面&…

EF性能優化(一)

1、EF SQL監控工具目前采用SQLServer 自帶的SQL Server Profiler來監控執行的sql&#xff0c;或者采用第三方插件MiniProfiler&#xff0c;具體用法可以網上查一下。2、EF使用SQlQuery 直接寫sqlEF效率低于ADO.NET是因為LINQ-TO-SQL的過程消耗了時間。而使用SqlQuery則可以直接…

解決Genymotion下載設備失敗的方法(Connection Timeout)

一直下載不下來&#xff0c;報錯。 解決辦法&#xff1a; 打開 C:\Users\用戶名\AppData\Local\Genymobile目錄 打開genymotion.log文件&#xff0c;在里面最下面幾行&#xff0c;找到如下日志 [Debug] Downloading file "http://files2.genymotion.com/dists/4.4.4/ova/…

尋仙服務器要維護多久,尋仙手游幾天開一個區

摘要尋仙手游最新開服時間表IOS和安卓&#xff0c;尋仙手游什么時候新增開服&#xff0c;開服時間公告。我們將于8月17日(周四)凌晨5:00-9:00對全服進行停機更新&#xff0c;請您提前保存游戲進程&#xff0c;安全下線。聽到很多小伙伴都在討論尋仙手游幾天開一個區&#xff0c…

Linux常用初級指令介紹

touch 文件名 ------可創建一個文件&#xff08;白色的字體&#xff09;rm * -rf -------刪除當前路徑下的全部文件Ctrlc :----強行終止當前程序Ctrld -----退出終端Ctrls ----暫停當前程序&#xff0c;然后按下任意鍵恢復運行Ctrlz ----將當前程序放在后臺運行&#xff0c;回…

如何寫出安全的API接口

通過園友們的討論&#xff0c;以及我自己查了些資料&#xff0c;然后對接口安全做一個相對完善的總結&#xff0c;承諾給大家寫個demo&#xff0c;今天一并放出。對于安全也是相對的&#xff0c;下面我來根據安全級別分析1.完全開放的接口有沒有這樣的接口&#xff0c;誰都可以…

Linux系統文件編程(1)

打開文件 int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode);open----返回的是文件描述符是整形數&#xff08;文件描述符在形式上是一個非負整數。實際上&#xff0c;它是一個索引值&#xff0c;指向內核為每一個進程所維…

【收集】常用的cmd命令

運行操作CMD命令&#xff1a;開始&#xff0d;>運行&#xff0d;>鍵入cmd或command(在命令行里可以看到系統版本、文件系統版本)CMD命令錦集1. gpedit.msc-----組策略2. sndrec32-------錄音機3. Nslookup-------IP地址偵測器 &#xff0c;是一個 監測網絡中 DNS 服務器是…