在CRUD四個操作中查找是從mongodb數(shù)據(jù)庫的集合中獲取一個記錄或者一個文檔。對于非DBA來說,使用的最多的就是查詢,所以說如果學(xué)好了查詢,對于我們將來更好的操作數(shù)據(jù)庫有很大的幫助。 在mongodb中從集合中獲得一條數(shù)據(jù)或者文檔可以通過以下兩個方法: find
在CRUD四個操作中查找是從mongodb數(shù)據(jù)庫的集合中獲取一個記錄或者一個文檔。對于非DBA來說,使用的最多的就是查詢,所以說如果學(xué)好了查詢,對于我們將來更好的操作數(shù)據(jù)庫有很大的幫助。
在mongodb中從集合中獲得一條數(shù)據(jù)或者文檔可以通過以下兩個方法:
find()
findOne()
find()是我們從數(shù)據(jù)庫中查找數(shù)據(jù)使用最主要的方法。find()語法如下:
db.[集合名].find(
類比SQL語句,query就相當(dāng)于我們SQL中的查詢條件,projection就相當(dāng)于SQL中SELECT后面我們需要的字段。默認情況下find()最多返回20條記錄。
在前面我們介紹了如果我們省略query、projection參數(shù)默認會返回集合中的文檔。
下面我們查詢一下user集合中name為user2的文檔:
> db.user.find()
{ "_id" : 1, "name" : "user1","age" : 11 }
{ "_id" : 2, "name" : "user2", "age": 12 }
{ "_id" : 3, "name" : "user3","age" : 13 }
{ "_id" : 4, "name" : "user4","age" : 14 }
{ "_id" : 5, "name" : "user5","age" : 15 }
{ "_id" : 6, "name" : "user6","age" : 16 }
{ "_id" : 7, "name" : "user7","age" : 17 }
{ "_id" : 8, "name" : "user8","age" : 18 }
{ "_id" : 9, "name" : "user9","age" : 19 }
{ "_id" : 10, "name" : "user10","age" : 20 }
> db.user.find({name:"user2"}) /*我們只是用了query參數(shù),默認返回所有字段,類似SQL中的SELECT * from table*/
{ "_id" : 2, "name" : "user2","age" : 12 }
上面的代碼中將文檔的所有字段都返回了,可能這個文檔小無所謂。如果對于一個很大的文檔,我們只需要一個字段,如果再這樣返回,那么我們就有點浪費了,這時候我們就可以使用projection參數(shù)。
我們自user表中查找name為user2的文檔,我們只想知道它的age,不需要它的name,我們可以向下面這樣:
> db.user.find({name:"user2"},{age:1})
{ "_id" : 2, "age" : 12 }
在mongodb中,對于非零都會認為為真,只有0會被當(dāng)做假,所以像上面的情況中使用true和false也可。包括自后面的代碼中,我也會經(jīng)常使用非0數(shù)代表真。
可能我們有人希望按照下面那樣寫projection參數(shù):
{name:0,age:1}
這樣再mongodb中錯誤的,mongodb中projection參數(shù),要不就只寫你需要的值(也就是值都為真),要不你就都寫不想要的值(值都為假),混合使用是不被接受的。
findOne()與find()基本相同,只是findONe()不管滿足查詢條件的文檔有多少,只會返回第一條數(shù)據(jù)。findOne()的語法和使用方法與find()一樣,這里就不再介紹了。
如果mongodb只是提供了上面介紹的查詢方式,那么mongodb號稱強大的查詢功能就太名不副實了。下面我們就來學(xué)習(xí)mongodb強大的查詢選擇器。
在mongodb的文檔中將其分為比較、邏輯、元素、javascript、地理空間、數(shù)據(jù)選擇器,我們也按照這個介紹。
比較選擇器
Mongodb提供的比較選擇器有$all、$gt、$gte、$lt、$lte、$in、$nin、$ne。
$all
語法:{ field: {$all: [
查找字段的值為數(shù)組,并且包含所有給定的值的文檔。
> db.phone.find()
{ "_id" : ObjectId("5198e20220c9b0dc40419385"),"num" : [ 1, 2, 3 ] }
{ "_id" : ObjectId("5198e21820c9b0dc40419386"),"num" : [ 4, 2, 3 ] }
{ "_id" : ObjectId("5198e22120c9b0dc40419387"),"num" : [ 1, 2, 5 ] }
> db.phone.find({num:{$all:[1,4]}}) /*同時包含1,4的沒有數(shù)據(jù)*/
> db.phone.find({num:{$all:[1,2]}})
{ "_id" : ObjectId("5198e20220c9b0dc40419385"),"num" : [ 1, 2, 3 ] }
{ "_id" : ObjectId("5198e22120c9b0dc40419387"),"num" : [ 1, 2, 5 ] }
$gt
語法:{field: {$gt:value} }
查找字段的值大于給定值的文檔。
> db.user.find({age:{$gt:6}})
{ "_id" : ObjectId("5198c286c686eb50e2c843b9"),"name" : "user7", "age" : 7 }
{ "_id" : ObjectId("5198c286c686eb50e2c843ba"),"name" : "user8", "age" : 8 }
{ "_id" : ObjectId("5198c286c686eb50e2c843bb"),"name" : "user9", "age" : 9 }
{ "_id" : ObjectId("5198c286c686eb50e2c843bc"),"name" : "user10", "age" : 10 }
{ "_id" : ObjectId("5198c3cac686eb50e2c843bd"),"name" : "user0", "age" : 20 }
$gte
語法:{field:{$gte: value} }
查找字段的值大于等于給定值的文檔。
> db.user.find({age:{$gt:6}})
{ "_id" : ObjectId("5198c286c686eb50e2c843b8"),"name" : "user6", "age" : 6 }
{ "_id" : ObjectId("5198c286c686eb50e2c843b9"),"name" : "user7", "age" : 7 }
{ "_id" : ObjectId("5198c286c686eb50e2c843ba"),"name" : "user8", "age" : 8 }
{ "_id" : ObjectId("5198c286c686eb50e2c843bb"),"name" : "user9", "age" : 9 }
{ "_id" : ObjectId("5198c286c686eb50e2c843bc"),"name" : "user10", "age" : 10 }
{ "_id" : ObjectId("5198c3cac686eb50e2c843bd"),"name" : "user0", "age" : 20 }
$lt
語法:{field: {$lt:value} }
查找字段的值小于給定值的文檔。
> db.user.find()
{ "_id" : 1, "name" : "user1","age" : 1 }
{ "_id" : 2, "name" : "user2","age" : 2 }
{ "_id" : 3, "name" : "user3","age" : 3 }
{ "_id" : 4, "name" : "user4","age" : 4 }
{ "_id" : 5, "name" : "user5","age" : 5 }
{ "_id" : 6, "name" : "user6","age" : 6 }
{ "_id" : 7, "name" : "user7","age" : 7 }
{ "_id" : 8, "name" : "user8","age" : 8 }
{ "_id" : 9, "name" : "user9","age" : 9 }
{ "_id" : 10, "name" : "user10","age" : 10 }
> db.user.find({age:{$lt:5}})
{ "_id" : 1, "name" : "user1","age" : 1 }
{ "_id" : 2, "name" : "user2","age" : 2 }
{ "_id" : 3, "name" : "user3","age" : 3 }
{ "_id" : 4, "name" : "user4","age" : 4 }
$lte
語法:{field: {$lte:value} }
查找字段的值小于等于給定值的文檔。
> db.user.find()
{ "_id" : 1, "name" : "user1","age" : 1 }
{ "_id" : 2, "name" : "user2","age" : 2 }
{ "_id" : 3, "name" : "user3","age" : 3 }
{ "_id" : 4, "name" : "user4","age" : 4 }
{ "_id" : 5, "name" : "user5","age" : 5 }
{ "_id" : 6, "name" : "user6","age" : 6 }
{ "_id" : 7, "name" : "user7","age" : 7 }
{ "_id" : 8, "name" : "user8","age" : 8 }
{ "_id" : 9, "name" : "user9","age" : 9 }
{ "_id" : 10, "name" : "user10","age" : 10 }
> db.user.find({age:{$lte:5}})
{ "_id" : 1, "name" : "user1","age" : 1 }
{ "_id" : 2, "name" : "user2","age" : 2 }
{ "_id" : 3, "name" : "user3","age" : 3 }
{ "_id" : 4, "name" : "user4","age" : 4 }
{ "_id" : 5, "name" : "user5","age" : 5 }
$in
語法:{ field: {$in: [
查找字段的值為數(shù)組,并且包含一個或多個給定的值的文檔。
> db.c2.find()
{ "_id" : ObjectId("519d4db8f90a444101408c2c"),"ary" : [ 1, 2 ] }
{ "_id" : ObjectId("519d4dbcf90a444101408c2d"),"ary" : [ 1, 3 ] }
{ "_id" : ObjectId("519d4dc4f90a444101408c2e"),"ary" : [ 4, 5, 6 ] }
> db.c2.find({ary:{$in:[1,2]}})
{ "_id" : ObjectId("519d4db8f90a444101408c2c"),"ary" : [ 1, 2 ] }
{ "_id" : ObjectId("519d4dbcf90a444101408c2d"),"ary" : [ 1, 3 ] }
$nin
語法:{ field: {$nin: [
查找字段的值為數(shù)組,并且不包含一個或多個給定的值的文檔。
> db.c2.find()
{ "_id" : ObjectId("519d4db8f90a444101408c2c"),"ary" : [ 1, 2 ] }
{ "_id" : ObjectId("519d4dbcf90a444101408c2d"),"ary" : [ 1, 3 ] }
{ "_id" : ObjectId("519d4dc4f90a444101408c2e"),"ary" : [ 4, 5, 6 ] }
> db.c2.find({ary:{$nin:[1,2]}})
{ "_id" : ObjectId("519d4dc4f90a444101408c2e"),"ary" : [ 4, 5, 6 ] }
$ne
語法:{field:{$ne: value} }
查找字段不等于給定的值或者不存在此字段的文檔。
> db.user.find()
{ "_id" : 1, "name" : "user1","age" : 1 }
{ "_id" : 2, "name" : "user2","age" : 2 }
{ "_id" : 3, "name" : "user3","age" : 3 }
{ "_id" : 4, "name" : "user4","age" : 4 }
{ "_id" : 5, "name" : "user5","age" : 5 }
{ "_id" : 6, "name" : "user6","age" : 6 }
{ "_id" : 7, "name" : "user7","age" : 7 }
{ "_id" : 8, "name" : "user8","age" : 8 }
{ "_id" : 9, "name" : "user9","age" : 9 }
{ "_id" : 10, "name" : "user10","age" : 10 }
> db.user.find({age:{$ne:1}})
{ "_id" : 2, "name" : "user2","age" : 2 }
{ "_id" : 3, "name" : "user3","age" : 3 }
{ "_id" : 4, "name" : "user4","age" : 4 }
{ "_id" : 5, "name" : "user5","age" : 5 }
{ "_id" : 6, "name" : "user6","age" : 6 }
{ "_id" : 7, "name" : "user7","age" : 7 }
{ "_id" : 8, "name" : "user8","age" : 8 }
{ "_id" : 9, "name" : "user9","age" : 9 }
{ "_id" : 10, "name" : "user10","age" : 10 }
> db.user.find({sex:{$ne:1}}) /*不存在sex字段,將所有文檔都查出來*/
{ "_id" : 1, "name" : "user1","age" : 1 }
{ "_id" : 2, "name" : "user2","age" : 2 }
{ "_id" : 3, "name" : "user3","age" : 3 }
{ "_id" : 4, "name" : "user4","age" : 4 }
{ "_id" : 5, "name" : "user5","age" : 5 }
{ "_id" : 6, "name" : "user6","age" : 6 }
{ "_id" : 7, "name" : "user7","age" : 7 }
{ "_id" : 8, "name" : "user8","age" : 8 }
{ "_id" : 9, "name" : "user9","age" : 9 }
{ "_id" : 10, "name" : "user10","age" : 10 }
邏輯選取器
顧名思義這組選擇器是跟邏輯有關(guān)系的,有$and、$not、$or、$nor。
$and
語法:{ $and: [{
查找滿足所有給定條件的文檔,這里使用數(shù)組存放所有的條件。$and在執(zhí)行的時候如果第一個條件不滿足,就會短路不在繼續(xù)執(zhí)行了。
> db.user.find()
{ "_id" : 1, "name" : "user1","age" : 1 }
{ "_id" : 2, "name" : "user2","age" : 2 }
{ "_id" : 3, "name" : "user3","age" : 3 }
{ "_id" : 4, "name" : "user4","age" : 4 }
{ "_id" : 5, "name" : "user5","age" : 5 }
{ "_id" : 6, "name" : "user6","age" : 6 }
{ "_id" : 7, "name" : "user7","age" : 7 }
{ "_id" : 8, "name" : "user8","age" : 8 }
{ "_id" : 9, "name" : "user9","age" : 9 }
{ "_id" : 10, "name" : "user10","age" : 10 }
> db.user.find({$and:[{name:"user1"},{age:2}]})
> db.user.find({$and:[{name:"user1"},{age:1}]})
{ "_id" : 1, "name" : "user1","age" : 1 }
$and一般都可以轉(zhuǎn)換成為普通的查詢,例如上面的完全可以轉(zhuǎn)換為:
db.user.find({name:”user1”,age:1})
既然都可以轉(zhuǎn)換為不適用$and的方法查詢,那為何還需要使用and呢?因為使用簡單方法查詢?nèi)绻麠l件太多的話或者結(jié)合其他選擇器的時候比較混亂,使用$and會比較清晰。
$not
語法:{ field: {$not: {
查找不匹配所給定查詢表達式的文檔。
> db.user.find()
{ "_id" : 1, "name" : "user1","age" : 1 }
{ "_id" : 2, "name" : "user2","age" : 2 }
{ "_id" : 3, "name" : "user3","age" : 3 }
{ "_id" : 4, "name" : "user4","age" : 4 }
{ "_id" : 5, "name" : "user5","age" : 5 }
{ "_id" : 6, "name" : "user6","age" : 6 }
{ "_id" : 7, "name" : "user7","age" : 7 }
{ "_id" : 8, "name" : "user8","age" : 8 }
{ "_id" : 9, "name" : "user9","age" : 9 }
{ "_id" : 10, "name" : "user10","age" : 10 }
> db.user.find({age:{$not:{$gt:5}}}) /*查找age不大于5的文檔*/
{ "_id" : 1, "name" : "user1","age" : 1 }
{ "_id" : 2, "name" : "user2","age" : 2 }
{ "_id" : 3, "name" : "user3","age" : 3 }
{ "_id" : 4, "name" : "user4","age" : 4 }
{ "_id" : 5, "name" : "user5","age" : 5 }
$or
語法:{ $or: [ {
查找滿足表達式數(shù)組其中一個的文檔。
> db.user.find()
{ "_id" : 1, "name" : "user1","age" : 1 }
{ "_id" : 2, "name" : "user2","age" : 2 }
{ "_id" : 3, "name" : "user3","age" : 3 }
{ "_id" : 4, "name" : "user4","age" : 4 }
{ "_id" : 5, "name" : "user5","age" : 5 }
{ "_id" : 6, "name" : "user6","age" : 6 }
{ "_id" : 7, "name" : "user7","age" : 7 }
{ "_id" : 8, "name" : "user8","age" : 8 }
{ "_id" : 9, "name" : "user9","age" : 9 }
{ "_id" : 10, "name" : "user10","age" : 10 }
> db.user.find({$or:[{name:"user1"},{age:10}]}) /*查找name為user1,或者age為10的文檔*/
{ "_id" : 1, "name" : "user1","age" : 1 }
{ "_id" : 10, "name" : "user10","age" : 10 }
$nor
語法:{ $nor: [{
查找不滿足給定表達式數(shù)組中任意表達式的文檔。
> db.user.find()
{ "_id" : 1, "name" : "user1","age" : 1 }
{ "_id" : 2, "name" : "user2","age" : 2 }
{ "_id" : 3, "name" : "user3","age" : 3 }
{ "_id" : 4, "name" : "user4","age" : 4 }
{ "_id" : 5, "name" : "user5","age" : 5 }
{ "_id" : 6, "name" : "user6","age" : 6 }
{ "_id" : 7, "name" : "user7","age" : 7 }
{ "_id" : 8, "name" : "user8","age" : 8 }
{ "_id" : 9, "name" : "user9","age" : 9 }
{ "_id" : 10, "name" : "user10","age" : 10 }
> db.user.find({$nor:[{name:"user1"},{age:10}]}) /*查找name不為user1或者age不是10的數(shù)組*/
{ "_id" : 2, "name" : "user2","age" : 2 }
{ "_id" : 3, "name" : "user3","age" : 3 }
{ "_id" : 4, "name" : "user4","age" : 4 }
{ "_id" : 5, "name" : "user5","age" : 5 }
{ "_id" : 6, "name" : "user6","age" : 6 }
{ "_id" : 7, "name" : "user7","age" : 7 }
{ "_id" : 8, "name" : "user8","age" : 8 }
{ "_id" : 9, "name" : "user9","age" : 9 }
元素選擇器(Element)
在mongodb的文檔中叫做Element,翻譯成元素選擇器總是感覺有點別扭,但是也沒有找到更好的。
此類選擇器包括$exists、$mod、$type。
$exists
語法:{ field: {$exists:
查找是否存在某字段的文檔。True表示存在,false表示不存在。
> db.c2.find()
{ "_id" : 1, "name" : "yue" }
{ "_id" : 2, "age" : 2 }
> db.c2.find({name:{$exists:1}}) /*查找存在name字段的文檔*/
{ "_id" : 1, "name" : "yue" }
> db.c2.find({name:{$exists:0}}) /*查找不存在age字段的文檔*/
{ "_id" : 2, "age" : 2 }
$mod
語法:{ field: {$mod: [ divisor, remainder ]} }
選取某字段滿足模取運算的文檔。該字段的值必須為數(shù)字,否則查不到結(jié)果。
> db.c2.find()
{ "_id" : 1, "name" : "yue" }
{ "_id" : 2, "age" : 2 }
{ "_id" : 3, "age" : 15 }
> db.c2.find({age:{$mod:[2,1]}}) /*age取模2余1的文檔*/
{ "_id" : 3, "age" : 15 }
> db.c2.find({name:{$mod:[2,1]}})
$type
語法:{ field: {$type:
按照字段的類型查找文檔。每種類型對應(yīng)的數(shù)字,下面已經(jīng)列出了。
類型 |
編號 |
雙精度 |
1 |
字符串 |
2 |
對象 |
3 |
數(shù)組 |
4 |
二進制數(shù)據(jù) |
5 |
對象 ID |
7 |
布爾值 |
8 |
日期 |
9 |
空 |
10 |
正則表達式 |
11 |
JavaScript |
13 |
符號 |
14 |
JavaScript(帶范圍) |
15 |
32 位整數(shù) |
16 |
時間戳 |
17 |
64 位整數(shù) |
18 |
最小鍵 |
255 |
最大鍵 |
127 |
在mongodbshell中某些類型是不存在的,比如數(shù)字32位精度表示的是雙精度。
> db.c2.find()
{ "_id" : 1, "name" : "yue" }
{ "_id" : 2, "age" : 2 }
{ "_id" : 3, "age" : 15 }
> db.c2.find({age:{$type:1}}) /*age類型為雙精度的文檔*/
{ "_id" : 2, "age" : 2 }
{ "_id" : 3, "age" : 15 }
Javascript選擇器
此類選擇器包括$regex、$where。
$regex
查找滿足正則表達式的文檔。
>db.user.find()
{"_id" : 1, "name" : "user1", "age" : 1}
{"_id" : 2, "name" : "user2", "age" : 2}
{"_id" : 3, "name" : "user3", "age" : 3}
{"_id" : 4, "name" : "user4", "age" : 4}
{"_id" : 5, "name" : "user5", "age" : 5}
{"_id" : 6, "sex" : "nan" }
>db.user.find({name:/user*/i})
{"_id" : 1, "name" : "user1", "age" : 1}
{"_id" : 2, "name" : "user2", "age" : 2}
{"_id" : 3, "name" : "user3", "age" : 3}
{"_id" : 4, "name" : "user4", "age" : 4}
{"_id" : 5, "name" : "user5", "age" : 5}
Mongodb中的regex兼容perl,類似上面代碼中的正則表達式是比較方便的。Mongodb同樣也可以使用$regex方法。例子如下:
>db.user.find()
{"_id" : 1, "name" : "user1", "age" : 1}
{"_id" : 2, "name" : "user2", "age" : 2}
{"_id" : 3, "name" : "user3", "age" : 3}
{"_id" : 4, "name" : "user4", "age" : 4}
{"_id" : 5, "name" : "user5", "age" : 5}
{"_id" : 6, "sex" : "nan" }
>db.user.find({name:{$regex:"user*",$options:"i"}}) /*$options設(shè)置正則選項*/
{"_id" : 1, "name" : "user1", "age" : 1}
{"_id" : 2, "name" : "user2", "age" : 2}
{"_id" : 3, "name" : "user3", "age" : 3}
{"_id" : 4, "name" : "user4", "age" : 4}
{"_id" : 5, "name" : "user5", "age" : 5}
$where
$where可以根據(jù)表達式或者function查找滿足的文檔。使用function的時候如果返回的是true,則查找出此文檔。
>db.user.find()
{"_id" : 1, "name" : "user1", "age" : 1}
{"_id" : 2, "name" : "user2", "age" : 2}
{"_id" : 3, "name" : "user3", "age" : 3}
{"_id" : 4, "name" : "user4", "age" : 4}
{"_id" : 5, "name" : "user5", "age" : 5}
{"_id" : 6, "sex" : "nan" }
>db.user.find({$where:"this.sex == 'nan'"})
{"_id" : 6, "sex" : "nan" }
>db.user.find({$where:"obj.sex == 'nan'"})
{"_id" : 6, "sex" : "nan" }
>db.user.find({$where:function(){return this.sex == 'nan';}})
{"_id" : 6, "sex" : "nan" }
>db.user.find({$where:function(){return obj.sex == 'nan';}})
{"_id" : 6, "sex" : "nan" }
以上代碼中的this和obj都代表當(dāng)前的文檔。
地理位置選擇器
參看4.5地理空間搜索
數(shù)組選擇器
數(shù)組選擇器主要是對數(shù)組操作的,包括$elemMatch、$size。
$elemMatch
對于字段的值是數(shù)組,而且數(shù)組中的元素是內(nèi)嵌的文檔,在我們根據(jù)數(shù)組中的內(nèi)嵌文檔做查詢的時候,需要 $elemMatch。
>db.c3.find()
{"_id" : 1, "array" : [ { "value1" : 1,"value2" : 0 }, { "value1" : 2, "value2" : 2 } ]}
> db.c3.find({ array: { $elemMatch: { value1: 1, value2: { $gt: 1 } } } } )
> db.c3.find({ array: { $elemMatch: { value1: 1, value2: { $lt: 1 } } } } )
{"_id" : 1, "array" : [ { "value1" : 1,"value2" : 0 }, { "value1" : 2, "value2" : 2 } ]}
從上面的代碼中可以看出$elemMath會循環(huán)數(shù)組中的每一內(nèi)嵌文檔,然后與給定的條件進行比較,查找出滿足條件的文檔。
$size
語法:db.collection.find({ field: { $size:
查找出數(shù)組的長度滿足給定值的數(shù)組。
>db.c4.find()
{"_id" : 1, "ary" : [ 1 ] }
{"_id" : 2, "ary" : [ 2, 3 ] }
{"_id" : 3, "ary" : [ 4, 5, 6 ] }
>db.c4.find({ary:{$size:5}}) /*沒有數(shù)組長度等于5的文檔*/
>db.c4.find({ary:{$size:2}})
{"_id" : 2, "ary" : [ 2, 3 ] }
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com