這是mongo第三篇“查終結篇”,後續會連續更新5篇
mongodb的文章總結上會有一系列的文章,順序是先學會怎麼用,在學會怎麼用好,戒急戒躁,循序漸進,跟著我一起來探索交流。
通過上兩篇基的介紹,我相信大家對我有了初步的認識,簡單查詢得心用手,其實在資料工作中查詢中還遠遠不夠,今天我們在來總結查詢的其它常用操作。宣告,小編也是邊學變總結,如果有總結的不到位的地方,希望您多多指點。
01 簡述
通過上一篇文件,我們一起總結了mongodb查詢的使用和常見的查詢條件識別符號。本文主要在此基礎上進一步加深應用,主要從:邏輯查詢符、分頁查詢、排序、聚合查詢四方面來學習。哈哈,如果你基礎很好了,當然可以完全不用看了,其實在看一下也許會有不一樣的收穫呢…是吧!
在操作前,先把資料庫初始化好。向資料庫testdb的user集合初始化如下5條資料
db.user.insert([ {name:"程式設計師修煉之旅",age:2,from: "CTU",score:100 }, {name: "mongdb",age:13,from: "USA",score:90 }, {name: "mysql",age:23,from: "USA",score:86 }, {name: "orcle",age:45,from: "USA",score:75 }, {name: "sqlsrver", age:55,from: "USA",score:66}])
02 邏輯查詢符
邏輯操作符其實簡單的理解就是將不同的單元查詢符組合,通過邏輯運算子來進行邏輯判斷。邏輯查詢符主要包括:$and、$or、$nor、$not。下面對每一個邏輯查詢符進行實操舉例說明。
符號:$and(與)
說明:獲取子句中的所有條件都同時匹配的所有文件,$and使用短路求值,既如果第一個表示式的結果是false,MongoDB將不會執行剩餘的表示式。
語法:{$and:[{條件1},{條件2 },…,{ 條件N }]}
例項:
// 查詢name中包含了‘l’,並且年齡大於35的資料 db.user.find({$and:[{name:/l/i},{age:{$gt:35}}]}) // 查詢出orcle、sqlsrver兩條資料。 // 其實以查詢與db.user.find({name:/l/i,age:{$gt:35}})等價
符號:$nor:(非)
說明:與$or剛剛相反,獲取子句中的一個條件都不匹配的所有文件,$nor樣使用短路求值,既如果第一個表示式的結果是true,MongoDB將不會執行剩餘的表示式。
語法: {$nor:[{條件1},{條件2},…,{ 條件N }]}
例項:
// 查詢name中不包含了‘l’,並且年齡不能大於35的資料 db.user.find({$nor:[{name:/l/i},{age:{$gt:35}}]}) // 查詢出程式設計師修煉之旅、mongodb兩條資料。
符號:$not:(取反)
說明:選擇出不能匹配表示式的文件,包括沒有指定鍵的文件。$not操作符不能獨立使用,必須跟其他操作一起使用(除$regex)。其實簡單的理解,$not是對前面將的單一操作符的修飾。如果對單一操作符瞭解的,可以檢視上一篇文章:我叫Mongo,收了「查詢基礎篇」,值得你擁有
語法: {field:{ $not:{單一操作符表示式}}}
例項:
// 查詢name中不包含l的資料 b.user.find({name:{$not:/l/i}}) // 查詢出程式設計師修煉之旅、mongodb兩條資料。 // 查詢age不大於23(小於等於23)的資料 db.user.find({age:{$not:{$gt:23}}}) // 查詢出程式設計師修煉之旅、mongodb、mysql三條資料。
03
查詢綜合應用
關於查詢條件單個操作符和邏輯查詢符都掌握了,那麼在實際工作中,不是簡單的單個使用,需要多種情況綜合使用,在使用過程中,我們用搭積木的思想來組裝,把操作當著積木,一個一個拼接組合。
來幾個例項更清楚:
// 例項1: // 查詢name中包含字母l或o,並且age除以3取模為1 // 命令書寫思路,改條件包括3個查詢積木組成: // name中包含字母l: {name:/l/i} // name中包含字母o: {name:/o/i} // age除以3取模為2: {age:{$mod:[3,1]}} // 前兩查詢積木通過邏輯查詢符$or構成前半截查詢命令 {$or:[{name:/l/i},{name:/o/i}]} // 前後命令通過$and邏輯查詢符構造完整的查下命令 db.user.find({$and:[{$or:[{name:/l/i},{name:/o/i}]},{age:{$mod:[3,1]}}]}) // 查詢結果:查詢mysql、sqlsrver兩條資料 // 例項2:在例項1的基礎上在新增一個條件,score不大於80 // 新增條件對應的條件積木為:{score:{$not:{$gt:80}}} // 在將新增的條件積木,組裝到上述並列條件即可最終的查詢命令 db.user.find({$and:[{$or:[{name:/l/i},{name:/o/i}]},{age:{$mod:[3,1]}},{score:{$not:{$gt:80}}}]}) // 查詢結果:查詢sqlsrver一條資料
通過上面的例項,其實我們在對複雜查詢,要思路清晰,就按照堆積木的思想,一層一層的拆解組裝,最終就構成了完整的查詢命令。
04 排序
Mongodb排序實現上很簡單通過sort()方法,指定引數來排序,並可以根據一個或者多個節點來排序。
語法:.sort({file1: sortType,...,filen: sortType})
其中 sortType指排序方式列舉值,其中1:升序;-1:降序
例項:
// 查詢score大86的資料,查詢結果按照from降序score升序排列 db.user.find({score:{$gte:80}}).sort({from:-1,score:1}) // 查詢結果的資料順序為:mysql、mongdb、程式設計師修煉之旅 //將上述查詢按照from升序score降序排列 db.user.find({score:{$gte:80}}).sort({from:1,score:-1}) // 查詢結果的資料順序為:程式設計師修煉之旅、mongdb、mysql
排序是不是使用起來很簡單,就點到為止。
05 分頁查詢
我們在實際工作中,分頁查詢是繞不開的操作,分頁查詢效率也是逃不掉的話題。本次先研究如何使用分頁查詢,後續專門在來研究探討查詢效率問題。
首先,我們還是規規矩矩的按照通用的方式來實現分頁查詢,分頁查詢其效果就是要實現從某一個位置開始取指定條數的資料。這就引出了兩個方法,查詢開始(skip),獲取指定條數資料(limit)。
- skip語法為skip(num):指跳過指定條數(num)的資料;
- limit語法為limit(num):指限制只獲取num條資料;
分頁查詢語法格式:
db.collection.fin(查詢條件).sort(排序方式).skip((頁碼-1)*每頁資料條數).limit(每頁資料條數)
例項:按照score升序排序,每頁資料條數為2,查詢score大於50的第2頁資料
db.user.find({score:{$gte:50}}).skip((2-1)*2).sort({score:1}).limit(2) // 查詢結果的資料順序為:、mysql、mongdb兩條資料
skip+ limit組合實現分頁查詢就是這麼簡單,並且也是同樣的分頁查詢方式,但是改方式不是最優的查詢方式,隨著頁碼的增加,效率越來越低(這是因為Skip是一條一條的數過來的)。在實際工作中,我們可以根據資料關係進行高效能的分頁查詢實現,本次就不在探討,後續專門探討改問題。
06 求和
Mongodb提供了count(applySkipLimit)進行求和,是一個比較常見的函式,使用簡單,但是有一個點需要注意的是其引數的使用。
applySkipLimit:是一個bool值,代表是否應用於skip好limit函式,true:代表當應用於skip和limit是,返回最終限制後的資料條數;false:代表返回資料條數不受skip和limit函式的影響;預設值為false。還是用例子說事。
// 查詢 from不等於CTU的資料同條數 db.user.find({from:{$not:{$eq:"CTU"}}}).count() // 查詢結果為 4 db.user.find({from:{$not:{$eq:"CTU"}}}).count(true) // 查詢結果為 4 // 當查詢使用skip跳過第一條數時,獲取資料總條數 db.user.find({from:{$not:{$eq:"CTU"}}}).skip(1).count() // 查詢結果為 4 db.user.find({from:{$not:{$eq:"CTU"}}}).skip(1).count(true) // 查詢結果為 3 正常情況下,這才是我們想要的結果 // 當查詢使用limit限制查詢資料時,獲取資料總條數 db.user.find({from:{$not:{$eq:"CTU"}}}).limit(2).count() // 查詢結果為 4 db.user.find({from:{$not:{$eq:"CTU"}}}).limit(2).count(true) // 查詢結果為 2 正常情況下,這才是我們想要的結果
通過上面的例項我們得知applySkipLimit只有遇到skip或者limit函式才生效,平時在使用的時候這也是一個需要注意的點。
07 小結
通過本問和上兩篇文章的總結,現在對mongodb的基礎已經總結告一段落。本文重點對通過例項對查詢中的邏輯符($and、$or、$nor、$not)和查詢常用函式(sort、skip、limit、count)四個函式使用進行重點介紹。通過例項我相信能夠解決實際工作的60%的問題。接下來的主要對mongodb的高階操作進行學習總結,期待您的持續關注與支援,謝謝!