我叫Mongo,幹了「查詢終結篇」,值得您擁有

程式設計師修煉之旅發表於2020-11-11

這是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的高階操作進行學習總結,期待您的持續關注與支援,謝謝!

相關文章