閱讀目錄
- 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對結果分頁的。