我們先來(lái)看看下面的表格
作用 | SQL | MongoDB |
查詢(xún)所有記錄 | SELECT * FROM users | db.users.find() |
查詢(xún)age=33的記錄 | SELECT * FROM users WHERE age=33 | db.users.find({age:33}) |
子鍵(字段)篩選 | SELECT a, b FROM users WHERE age=33 | db.users.find({age:33}, {a:1,b:1}) |
排序 | SELECT * FROM users WHERE age=33 ORDER BY name | db.users.find({age:33}).sort({name:1}) |
比大小 | SELECT * FROM users WHERE age>33 | db.users.find({'age':{$gt:33}})}) |
正則(模糊匹配) | SELECT * FROM users WHERE name LIKE "Joe%" | db.users.find({name:/^Joe/}) |
忽略、限制 | SELECT * FROM users LIMIT 10 SKIP 20 | db.users.find().limit(10).skip(20) |
Or操作 | SELECT * FROM users WHERE a=1 or b=2 | db.users.find({$or:[ {a:1} , {b:2}] }) |
僅返回1條(TOP 1) | SELECT * FROM users LIMIT 1 | db.users.findOne() |
Distinct聚合 | SELECT DISTINCT last_name FROM users | db.users.distinct('last_name') |
Count聚合 | SELECT COUNT(AGE) from users | db.users.find({age: {'$exists': true}}).count() |
查詢(xún)計(jì)劃 | EXPLAIN SELECT * FROM users WHERE z=3 | db.users.find({z:3}).explain() |
子鍵篩選
子鍵篩選也就是我們?cè)?SQL 數(shù)據(jù)庫(kù)中見(jiàn)怪不怪的字段篩選。然而,由于MongoDB 采用的是基于 Json 的查詢(xún)語(yǔ)句,所以其子鍵篩選顯得非常怪異(限于篇幅,請(qǐng)留意示例代碼中的注釋):
// 包含所有子鍵
db.users.find({age:33})
// 僅包含子鍵:_id、a、b
db.users.find({age:33}, {a:1, b:1});
// 僅包含子鍵:_id、a
db.users.find({age:33}, {a:1, });
// 僅包含子鍵(這里給出了剔除_id的方法):a
db.users.find({age:33}, {a:1, b:0, });
復(fù)雜查詢(xún)
MongoDB 可以支持一些比較操作(大于小于)、子句( or )、取反( not )等查詢(xún),同樣的,請(qǐng)觀察示例代碼:
// 實(shí)際上它們都是查詢(xún)操作符!
// 返回年齡大于等于33歲,且小于40歲的用戶(hù):
db.users.find({ age: { ‘$gte’ : 33, ‘$lt’ : 40 } });
// 返回年齡大于33歲,且不等于40歲的用戶(hù):
db.users.find({ age: { ‘$gte’ : 33, ‘$ne’ : 40 } });
// 返回年齡等于33歲,或等于40歲的用戶(hù):
db.users.find({ ‘$or’: [ {‘age’ : 33}, {‘age’ : 40} ] });
注意:默認(rèn)情況下,MongoDB執(zhí)行的是and操作,即所有指定的條件都是與的關(guān)系。只有在特別的情況下,才會(huì)使用或(or),而$or就是MongoDB的或子句。
查詢(xún)條件操作符
操作符 | 說(shuō)明 | 示例 |
$lt,$lte,$gt,$gte | <, <=, >, >= | db.things.find({ a: { $gt: value } } ); |
$all | 數(shù)組中的元素是否完全匹配 | db.things.find( { a: { $all: [ 2, 3 ] } } ); |
$exists | 可選:true,false | db.things.find( { a : { $exists : true } } ); |
$mod | 取模:a % 10 == 1 | db.things.find( { a : { $mod : [ 10 , 1 ] } } ); |
$ne | 取反:即not equals | db.things.find( { x : { $ne : 3 } } ); |
$nin | $in的反操作,即SQL的 NOT IN | db.things.find({j:{$nin: [2,4,6]}}); |
$nor | $or的反操作,即不匹配(a或b) | db.things.find( { name : "bob" , $nor : [ { a : 1 } , { b : 2 } ] } ) |
$or | Or子句,注意$or不能嵌套使用 | db.things.find( { name : "bob" , $or : [ { a : 1 } , { b : 2 } ] } ) |
$size | 匹配數(shù)組長(zhǎng)度 | db.things.find( { a : { $size: 1 } } ); |
$type | 匹配子鍵的數(shù)據(jù)類(lèi)型 | db.things.find( { a : { $type : 2 } } ); |
正則表達(dá)式
MongoDB 的正則表達(dá)式實(shí)現(xiàn)了 SQL 中的通配符匹配的機(jī)制,而且比 SQL 更加強(qiáng)大。不過(guò)可惜的是,只有類(lèi)似于 / ^ .+/ 這樣的前綴型正則表達(dá)式才能夠使用索引,其他形式都會(huì)做全集合掃描。
MongoDB 的正則表達(dá)式語(yǔ)法與 JavaScript 完全一致。
// 正則匹配方法之一
db.customers.find( { name : /acme.*corp/i } );
// 正則匹配方法之二
db.customers.find( { name : { $regex : 'acme.*corp', $options: 'i' } } );
// 與其他條件聯(lián)合使用
db.customers.find( { name : { $regex : /acme.*corp/i, $nin : [‘abc'] } } );
注意:MongoDB的正則表達(dá)式可以匹配其自身。如果您將正則表達(dá)式存入了MongoDB,那么查詢(xún)的時(shí)候,它可以匹配它自身!
數(shù)組查詢(xún)
MongoDB數(shù)組查詢(xún),除了之前提到的$all和$size等,還有:$size,$slice,子項(xiàng)定位和$elemMatch。
1.數(shù)組查詢(xún)之$size
$size 用來(lái)匹配數(shù)組長(zhǎng)度(即最大下標(biāo)):
/ 返回comments包含5個(gè)元素的文檔
db.posts.find({}, {comments:{‘$size’: 5}});
請(qǐng)注意:$size操作符并不能與其他查詢(xún)操作符(子句)聯(lián)合使用,這意味著您不能使用如下代碼:
// 以下的使用方法是錯(cuò)誤的
db.posts.find({}, {comments:{‘$size’: { ‘$gt’: 5 }}});
2.
$slice 操作符類(lèi)似于子鍵篩選,只不過(guò)它篩選的是數(shù)組中的項(xiàng)。
// 僅返回?cái)?shù)組中的前5項(xiàng)
db.posts.find({}, {comments:{‘$slice’: 5}});
// 僅返回?cái)?shù)組中的最后5項(xiàng)
db.posts.find({}, {comments:{‘$slice’: -5}});
// 跳過(guò)數(shù)組中的前20項(xiàng),返回接下來(lái)的10項(xiàng)
db.posts.find({}, {comments:{‘$slice’: [20, 10]}});
// 跳過(guò)數(shù)組中的最后20項(xiàng),返回接下來(lái)的10項(xiàng)
db.posts.find({}, {comments:{‘$slice’: [-20, 10]}});
3.
細(xì)心的童鞋已經(jīng)發(fā)現(xiàn),數(shù)組的子項(xiàng)定位已經(jīng)在上一個(gè)章節(jié)講過(guò)了。是的,是講過(guò)了,但我還是要再提一下,加深印象!MongoDB 允許在查詢(xún)中指定數(shù)組的下標(biāo),以實(shí)現(xiàn)更加精確的匹配。
本小節(jié)有且僅有一個(gè)簡(jiǎn)單的代碼示例:
// 返回comments中第1項(xiàng)的by子鍵為Abe的所有文檔
db.blogposts.find( { "comments.0.by" : "Abe" } );
4.數(shù)組查詢(xún)之$ elemmarch
童鞋們還記得上一集中我們提到的數(shù)組定位修改器中除了數(shù)組下標(biāo)還有一個(gè)“$ ”符號(hào)嗎?該符號(hào)在 find 中就不靈了,怎么辦呢?那就只有考慮使用 $elemMatch 操作符了,多說(shuō)無(wú)益,看代碼:
// 有這樣一個(gè)包含了2個(gè)文檔的集合,仔細(xì)觀察
// 現(xiàn)在我們需要找到 shape = "square" 且 color = "purple" 的那項(xiàng)
{ "foo" : [ { "shape" : "square", "color" : "purple", "thick" :
false }, { "shape" : "circle", "color" : "red", "thick" : true } ]};
{ "foo" : [ { "shape" : "square", "color" : "red", "thick" : true },
{ "shape" : "circle", "color" : "purple", "thick" : false } ]};
// 這兩個(gè)查詢(xún)都會(huì)同時(shí)匹配兩個(gè)文檔
db.foo.find({"foo.shape": "square", "foo.color": "purple"});
db.foo.find({foo: {"shape": "square", "color": "purple"} });
// 這才是我們想要的
db.foo.find({foo: {"$elemMatch": {shape: "square", color:
"purple"}}});
|
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注