深入理解mongodb查詢條件語句


閱讀目錄

1. 理解:"$lt"、"$lte"、"$gt" 和 "$gte"

首先在講解查詢條件之前,我們先看看我們的數據庫中有哪些基本的數據,我們可以使用如下代碼查詢下:如下代碼:

const mongo = require('mongodb');
const Server = mongo.Server;
const Db = mongo.Db;

const server = new Server('localhost', '27017', { auto_reconnect: true });
const db = new Db('dataDb', server, { safe: true });

db.open(function(err, db) {
  if (err) {
    throw err;
  } else {
    console.log('成功建立數據庫連接');
    db.collection('users', function(err, collection) {
      if (err) {
        throw err;
      } else {
        // 開始查詢集合users
        collection.find({}).toArray(function(err, docs) {
          if (err) {
            throw err;
          } else {
            console.log(docs);
            db.close();
          }
        });
      }
    });
  }
});

如下圖所示:

"$lt"、"$lte"、"$gt" 和 "$gte" 分別對應 <、<=、> 和 >=. 可以將其組合起來查找一個范圍的值。
現在我們想查詢年齡在 30歲到40歲的用戶,就可以使用如下命令了,如下代碼:

collection.find({"age" : {"$gte": 30, $lte: 40}});

所有代碼如下:

const mongo = require('mongodb');
const Server = mongo.Server;
const Db = mongo.Db;

const server = new Server('localhost', '27017', { auto_reconnect: true });
const db = new Db('dataDb', server, { safe: true });

db.open(function(err, db) {
  if (err) {
    throw err;
  } else {
    console.log('成功建立數據庫連接');
    db.collection('users', function(err, collection) {
      if (err) {
        throw err;
      } else {
        // 開始查詢集合users
        collection.find({"age" : {"$gte": 30, $lte: 40}}).toArray(function(err, docs) {
          if (err) {
            throw err;
          } else {
            console.log(docs);
            db.close();
          }
        });
      }
    });
  }
});

執行結果為:

注意: 下面的查詢我只會寫一句代碼哦,其他的代碼和上面代碼一樣,比如查詢代碼,只會寫這么一句:
collection.find({"age" : {"$gte": 30, $lte: 40}}),為了節約篇幅。

2. 理解 '$ne'

$ne' 的含義是,文檔的鍵值不等於某個特定值,它的含義是 表示 '不相等的意思'。比如我現在想查詢 名字不等於 'kongzhi'.

首先我們數據庫還是有如下數據:

我們可以像如下查詢:

collection.find({"name" : {"$ne": 'kongzhi'}})

含義是查詢文檔后,不包含 name = "kongzhi" 的所有數據,運行結果可以看到如下:

3. 理解 "$in" 和 "$or", 及 "$nin"

Mongodb中有兩種方式進行or查詢,"$in" 可以用來查詢一個鍵的多個值;"$or" 可以在多個鍵中查詢任意的給定值。

那么他們有什么區別呢?
1)'$in' 可以理解為 '包含的意思',比如說,我想查詢 name 包含 'longen1' 和 'longen2' 這兩個值的話,可以使用 '$in'
進行查詢。比如如下查詢語句:

collection.find({"name" : {"$in": ['longen1', 'longen2']}})

執行結果如下所示:

2)'$nin': 和 '$in' 相對應的是 '$nin', '$nin' 將返回與數組中所有條件都不匹配的文檔。比如說,我想返回數據不包含 'longen1' 和 'longen2' 的數據,可以使用如下命令:

collection.find({"name" : {"$nin": ['longen1', 'longen2']}})

執行結果如下所示:

3)'$or' 的含義是 '或者的意思',就是說 我既要查詢到 name='longen1', 還要查詢到 name='kongzhi1' 這樣的數據,就可以使用 '$or'了,'$or' 接受一個包含所有條件的數組作為參數。比如如下執行命令:

collection.find({"$or": [{"name": 'longen1'}, {"name": 'kongzhi1'}]})

執行結果如下所示:

4. 理解使用正則表達式來查詢

正則表達式能夠靈活有效地匹配字符串,比如說我想查找所有名為 "long" 的用戶,可以如下執行代碼:

collection.find({"name": /long/i});

查詢結果如下所示:

它可以模糊匹配到所有name字段含有 'long' 的字符串的,再比如,我匹配查找所有含有 'kong' 字符串的,執行代碼如下:

collection.find({"name": /kong/i});

查詢結果如下所示:

注意:使用正則匹配的方式和我們的javascript的正則匹配是一模一樣的語法。也就是說 兼容Perl的正則表達式的語法。

5. 理解查詢數組 $all, $size 操作符的使用

5.1) $all: 該操作符的含義是使用多個元素來模糊匹配數組,也就是說,如果多個數組里面包含 $all 匹配的內容的話,那么該數組都會被匹配出來。

假如現在users集合里面有如下數據:

我現在想匹配 "name": ['kongzhi', 'tugenhua'] 這樣的,把數組同時包含這兩個數據的數組匹配出來,可以如下代碼:

collection.find({"name": {$all: ['kongzhi', 'tugenhua']}})

執行結果如下:

如上也可以對整個數組進行精確匹配。

但是如果想查詢數組特定位置的元素,需要使用 key.index 語法指定下標:如下代碼:

collection.find({"name.0": 'kongzhi1'});

數組的下標都是從0開始的,所以上面的表達式會使用數組的第一個元素 和 kongzhi1 進行匹配。如下匹配的結果:

5.2)$size

該操作符的含義是 查詢特定長度的數組。如下代碼:

collection.find({"name": {"$size": 3}})

它的含義是 查詢 name字段的數組長度為3的。查詢結果如下:

如果我們現在把查詢的長度改為1或者2的話,比如如下代碼:

collection.find({"name": {"$size": 1}})

那么它就會什么都不能匹配到,如下所示:

6. 理解 limit, skip 和 sort

6.1) limit: 該操作符是限制結果數量的含義,可以在find后使用 limit函數,比如整個users集合里面有如下數據:

一共有6條數據。

現在我們使用limit函數,比如限制只返回3條數據,代碼可以如下寫:

collection.find().limit(3).toArray(function(err, docs) {})

執行結果如下所示:

limit指上限,可以理解為返回最多3個,但是如果數據庫集合里面數據沒有3個的話,那么就會返回匹配數量的結果。

6.2) skip 該操作符的含義是 跳過集合中的多少個數據,然后返回集合中剩下的數據,比如如下匹配代碼:

collection.find().skip(3).toArray(function(err, docs) {})

它會跳過集合中三個數據,然后返回集合中剩余的數據,執行結果如下所示:

6.3)sort, 該操作符接收一個對象作為參數,這個對象是一組 鍵/值對,鍵對應集合中的鍵名,值代表排序的方向,排序的方向可以是1(升序),或者 -1(降序)。如果指定了多個鍵,則按照這些鍵被指定的順序逐個排序。

比如我們現在想要按照 age 降序,代碼可以如下寫:

collection.find().sort({age: -1}).toArray(function(err, docs) {})

執行結果如下所示:

7. 實現分頁:

7.1)使用skip進行分頁:如上三個操作符可以組合使用,對於分頁來說非常有用,比如我想每頁返回2條數據,並且按age從高到底進行排序;可以如下寫代碼:

collection.find().limit(2).sort({age: -1}).toArray(function(err, docs) {})

執行結果如下所示:

當我們點擊下一頁的時候,可以查看更多的結果,我們可以通過skip實現,只需要跳過前面2條數據就好了。

collection.find().limit(2).skip(2).sort({age: -1}).toArray(function(err, docs) {})

執行結果如下:

因此我們可以簡單這樣實現一個分頁,根據傳進來的頁碼及一頁多少條來判斷。比如我們默認一頁10條數據,然后默認跳過0條,就是第一頁的數據,如果用戶傳遞進來當前的頁碼是2,每頁的條數是20條的話,那么就使用用戶傳遞進來的參數進行操作。

var page = 1,
pagesize = 10;

if ('用戶傳進來的頁碼') {
   page = '用戶傳進來的頁碼'
}

if ('用來傳進來的頁碼大小') {
   pagesize = '用戶傳進來的頁碼大小';
}

/*
跳過多少條的邏輯: 如果當前的頁碼是第一頁的話,那么就跳過0條;
如果當前的頁碼是大於1的話,比如第2頁,那么跳過的條數是 (2-1) * 一頁多少條數據
skipCount(跳過的條數的計算方式) = (page - 1) * pagesize;
*/

因此執行分頁的代碼如下:

collection.find().limit(pagesize).skip(skipCount).sort({age: -1}).toArray(function(err, docs) {})

注意:skip進行分頁有缺點的,如果使用skip跳過很多條數據的時候,查詢的速度會變得非常慢,因為我們先要找到需要被跳過
的數據,然后再拋棄這些數據。因此我們不要使用skip對結果分頁的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM