mongodb 高階查詢
其實內容並不難理解,主要照顧英語苦手的兄弟們,也方便自己。
這裡主要是講MongoDB在控制檯中如何進行高階查詢,既有教程內容,也有ME動手實驗的經驗,搞懂了這些規則,對於你再使用其他語言(Java,ruby,python等)實現查詢時有莫大的幫助,因為基礎的是相通的,只是不同的語言實現介面略有差異而已。
還有一句想提醒大家,多動手實驗,才是硬道理。
<,>,>=,<=
這四個就不用解釋了,最常用的,也是最簡單的。
db.collection.find({ "field" : { $gt: value } } ) // 大於 : field > value
db.collection.find({ "field" : { $lt: value } } ) // 小於 : field < value
db.collection.find({ "field" : { $gte: value } } ) // 大於等於 : field >= value
db.collection.find({ "field" : { $lte: value } } ) // 小於等於 : field <= value
如果要同時滿足多個條件,記得要這樣用:
db.collection.find({ "field" : { $gt: value1, $lt: value2 } } ) // value1 < field < value
$ne 不等於
db.things.find( { x : { $ne : 3 } } )
條件相當於x<>3,即x不等於3。
$mod 取模運算
db.things.find( { a : { $mod : [ 10 , 1 ] } } )
條件相當於a % 10 == 1 即a除以10餘數為1的。
$nin 不屬於
db.things.find({j:{$nin: [2,4,6]}})
條件相當於 j 不等於 [2,4,6] 中的任何一個。
$in 屬於
db.things.find({j:{$in: [2,4,6]}})
條件相當於j等於[2,4,6]中的任何一個。
$all 全部屬於
db.things.find( { a: { $all: [ 2, 3 ] } } )
與$in類似,但必須是[]的值全部都存在。
$size 數量,尺寸
db.things.find( { a : { $size: 1 } } )
條件相當於a的值的數量是1(a必須是陣列,一個值的情況不能算是數量為1的陣列)。
$exists 欄位存在
db.things.find( { a : { $exists : true } } )
db.things.find( { a : { $exists : false } } )
true返回存在欄位a的資料,false返回不存在字度a的資料。
$type 欄位型別
db.things.find( { a : { $type : 2 } } )
條件是a型別符合的話返回資料。
引數型別如下圖:
Type Name |
Type Number |
Double |
1 |
String |
2 |
Object |
3 |
Array |
4 |
Binary data |
5 |
Object id |
7 |
Boolean |
8 |
Date |
9 |
Null |
10 |
Regular expression |
11 |
JavaScript code |
13 |
Symbol |
14 |
JavaScript code with scope |
15 |
32-bit integer |
16 |
Timestamp |
17 |
64-bit integer |
18 |
Min key |
255 |
Max key |
127 |
Regular Expressions 正則表示式
db.customers.find( { name : /acme.*corp/i } )
類似sql中的like方法。
行開始 /^ 行結束 $/
這裡要特別特別特別地注意一點,關乎查詢效率:
While /^a/, /^a./, and /^a.$/ are equivalent and will all use an index in the same way, the later two require scanning the whole string so they will be slower. The first format can stop scanning after the prefix is matched.
意思大概就是指在查詢以a開頭字串時,可以有三種形式, /^a/, /^a./,和/^a.$/ 。後面兩種形式會掃描整個字串,查詢速度會變慢。第一種形式會在查到符合的開頭後停止掃描後面的字元。
所以要特別注意。
幾個附加引數:
i的意思是忽略大小寫。(這個很重要,很常用)
m的意思是支援多行。(不過ME沒有嘗試過)
x的意思是擴充套件。(也沒用過)
$or 或 (注意:MongoDB 1.5.3後版本可用)
db.foo.find( { $or : [ { a : 1 } , { b : 2 } ] } )
符合條件a=1的或者符合條件b=2的資料都會查詢出來。
與其他欄位一起查詢:
db.foo.find( { name : "bob" , $or : [ { a : 1 } , { b : 2 } ] } )
符合條件name等於bob,同時符合其他兩個條件中任意一個的資料。
Value in an Array 陣列中的值
例如資料庫中存在這樣的資料:
{ "_id" : ObjectId("4c503405645fa23b31e11631"), "colors" : [ "red", "black" ] }
查詢
db.things.find( { colors : "red" } );
即可查到上面那條資料。
$elemMatch 要素符合
t.find( { x : { $elemMatch : { a : 1, b : { $gt : 1 } } } } )
結果:
{ "_id" : ObjectId("4b5783300334000000000aa9"),
"x" : [ { "a" : 1, "b" : 3 }, 7, { "b" : 99 }, { "a" : 11 } ]
}
x其中一個要素符合那個檢索條件就可以被檢索出來。(不過一般誰用像x這樣的結構去儲存資料呢?)
Value in an Embedded Object 內嵌物件中的值
例如資料庫中存在這樣的資料:
{ "_id" : ObjectId("4c503773645fa23b31e11632"), "author" : { "name" : "Dan Brown", "age" : 38 }, "book" : "The Lost Symbol" }
查詢:
db.postings.find( { "author.name" : "Dan Brown" } );
即可查到上面那條資料。
查詢內嵌物件的屬性,記得要加上“”,欄位是“author.name”,而不是author.name。
$not 不是
db.customers.find( { name : { $not : /acme.*corp/i } } );
這是一個與其他查詢條件組合使用的操作符,不會單獨使用。
只要你理解了前面的查詢操作即可,只是再加上了$not,結果就是得到了沒有$not的相反結果集。
sort() 排序
這個非常實用。即sql語言中的OrderBy。
db.myCollection.find().sort( { ts : -1 } )
也可以多個欄位排序
db.myCollection.find().sort( { ts : -1 ,ds : 1 } )
這裡的1代表升序,-1代表降序。
經過ME的實驗,小於0的數字就是降序,0以上(包括0)就是升序。
limit() skip()
這兩個ME想連起來講,他們就是你實現資料庫分頁的好幫手。
limit()控制返回結果數量,如果引數是0,則當作沒有約束,limit()將不起作用。
skip()控制返回結果跳過多少數量,如果引數是0,則當作沒有約束,skip()將不起作用,或者說跳過了0條。
例如:
db.test.find().skip(5).limit(5)
結果就是取第6條到第10條資料。
snapshot() (沒有嘗試)
count() 條數
返回結果集的條數。
db.test.count()
在加入skip()和limit()這兩個操作時,要獲得實際返回的結果數,需要一個引數true,否則返回的是符合查詢條件的結果總數。
例子如下:
> db.test.find().skip(5).limit(5).count()
9
> db.test.find().skip(5).limit(5).count(true)
4