閱讀目錄
- 1. 理解:"$lt"、"$lte"、"$gt" 和 "$gte"
- 2. 理解 '$ne'
- 3. 理解 "$in" 和 "$or", 及 "$nin"
- 4. 理解使用正則表達式來查詢
- 5. 理解查詢數組 $all, $size 操作符的使用
- 6. 理解 limit, skip 和 sort
- 7. 實現分頁:
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對結果分頁的。