本文地址:http://www.cnblogs.com/egger/archive/2013/05/04/3059374.html 歡迎轉載 ,請保留此鏈接!
官方參考: http://docs.mongodb.org/manual/reference/operator/query/
查詢操作符(Query Operators)可以讓我們寫出複雜查詢條件,讓我們使用的過程更加靈活。
官方文檔中使用的“field”單詞,RDBMS中是字段的意思,但是MongoDB作爲文檔數據庫,使用的BSON格式作爲數據存儲格式。field對應key,我這裏還是把他翻譯成“字段”而不是“鍵”。若有不妥,請指出。
演示數據:
我們將實際操作下。先向集合inventory插入3條數據,文檔內容如下:
{"name":"t1","amount":16,"tags":[ "school", "book", "bag", "headphone", "appliances" ]}
{"name":"t2","amount":50,"tags":[ "appliances", "school", "book" ]}
{"name":"t3","amount":58,"tags":[ "bag", "school", "book" ]}
比較查詢操作符 Comparison Query Operators
$all
語法: { field: { $all: [ <value> , <value1> ... ] }
field:文檔中鍵的名稱(不使用雙引號)。
匹配那些指定鍵的鍵值中包含數組,而且該數組包含條件指定數組的所有元素的文檔。
db.inventory.find( { tags: { $all: [ "appliances", "school", "book" ] } } )
查詢出在集合inventory中 tags鍵值包含數組,且該數組中包含appliances、school、 book元素的所有文檔 ,因此該查詢將匹配tags鍵值包含如下任意數組的所有文檔。
[ "school", "book", "bag", "headphone", "appliances" ]
[ "appliances", "school", "book" ]
執行上面的查詢語句,
文檔中鍵值類型不是數組,也可以使用$all操作符進行查詢操作,如下例所示:
//查詢結果是相同的,匹配amount鍵值等於50的文檔 db.inventory.find( { amount: {$all:[50]}} ) db.inventory.find( { amount: 50}} )
$gt
語法:{field: {$gt: value} }
匹配鍵值大於指定值的所有文檔。
$gte
語法:{field: {$gte: value} }
匹配鍵值不小於指定值的所有文檔。
$lt
語法:{field: {$lt: value} }
匹配鍵值小於指定值的所有文檔。
$lte
語法:{field: {$lte: value} }
匹配鍵值不大於指定值的所有文檔。
//下面將查詢amount鍵值大於50的文檔: db.inventory.find( { amount: { $gt: 50 } } ) //下面將查詢amount鍵值不小於(大於等於)50的文檔: db.inventory.find( { amount: { $gte: 50 } } ) //下面將查詢amount鍵值小於50的文檔: db.inventory.find( { amount: { $lt: 50 } } ) //下面將查詢amount鍵值不大於(小於等於)50的文檔: db.inventory.find( { amount: { $lte: 50 } } )
$in
語法: { field: { $in: [<value1>, <value2>, ... <valueN> ] } }
匹配鍵值等於指定數組中任意值的文檔。類似sql中in.
$nin
語法: { field: { $nin: [ <value1>, <value2> ... <valueN> ]} }
匹配鍵不存在或者鍵值不等於指定數組的任意值的文檔。
查詢出amount鍵值爲16或者50的文檔:
db.inventory.find( { amount: { $in: [ 16, 50 ] } } )
//查詢出amount鍵值不爲16或者50的文檔 db.inventory.find( { amount: { $nin: [ 16, 50 ] } } ) //查詢出qty鍵值不爲16或50的文檔,由於文檔中都不存在鍵qty,所以返回所有文檔 db.inventory.find( { qty: { $nin: [ 16, 50 ] } } )
$ne
語法: {field: {$ne: value} }
匹配鍵值不等於指定值的文檔。
查詢出amount鍵值不等於58的文檔:
db.inventory.find( { amount: { $ne: 58 } } ) //$nin查詢結果相同 db.inventory.find( { amount: { $nin: [58] } } )
邏輯查詢操作符 Logical Query Operators
$and
語法: { $and: [ { <expression1> }, { <expression2> } , ... , { <expressionN> } ] }
$and 指定一個至少包含兩個表達式的數組,選擇出滿足該數組中所有表達式的文檔。$and操作符使用短路操作,若第一個表達式的值爲“false”,餘下的表達式將不會執行。
//選擇name爲“t1”,amount值小於50的文檔數據 db.inventory.find({ $and: [ { name: "t1" }, { amount: { $lt:50 } } ] } )
對於下面使用逗號分隔符的表達式列表,MongoDB會提供一個隱式的$and操作:
//等同於{ $and: [ { name: "t1" }, { amount: { $lt:50 } } ] } db.inventory.find({ name: "t1" , amount: { $lt:50 }} )
$nor
語法: { $nor: [ { <expression1> }, { <expression2> }, ... { <expressionN> } ] }
$nor執行邏輯NOR運算,指定一個至少包含兩個表達式的數組,選擇出都不滿足該數組中所有表達式的文檔。
//選擇name不爲“t1”,amount值不小於50的文檔數據 db.inventory.find( { $nor: [ { name: "t1" }, { qty: { $lt: 50 } } ] } )
//若是文檔中不存在表達式中指定的鍵,表達式值爲false; false nor false 等於 true,所以選擇集合所有文檔 db.inventory.find( { $nor: [ { sale: true }, { qty: { $lt: 50 } } ] } )
$not
語法: { field: { $not: { <operator-expression> } } }
$not執行邏輯NOT運算,選擇出不能匹配表達式的文檔 ,包括沒有指定鍵的文檔。
$not操作符不能獨立使用,必須跟其他操作一起使用(除$regex)。
//選擇amount值不大於50的文檔數據 db.inventory.find( { amount: { $not: { $gt: 50 } } } )
//指定的鍵gty,文檔中都不存在無法匹配表示,所以返回集合所有文檔數據。 db.inventory.find( { gty: { $not: { $gt: 50 } } } )
$or
語法: { $or: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] }
$or執行邏輯OR運算,指定一個至少包含兩個表達式的數組,選擇出至少滿足數組中一條表達式的文檔。
//選擇amount的鍵值大於50或者name的鍵值爲t1的文檔 db.inventory.find( { $or: [ { amount: { $gt: 50 } }, { name: "t1" } ] } )
元素查詢操作符 Element Query Operators
$exists
語法: { field: { $exists: <boolean> } }
如果$exists的值爲true,選擇存在該字段的文檔;若值爲false則選擇不包含該字段的文檔。
//查詢不存在qty字段的文檔(所有文檔) db.inventory.find( { qty: { $exists: false } }) //查詢amount字段存在,且值不等於16和58的文檔 db.inventory.find( { amount: { $exists: true, $nin: [ 16, 58 ] } } )
如果該字段的值爲null,$exists的值爲true會返回該條文檔,false則不返回。
//向集合中插入一條amount鍵值爲null的文檔 {"name":"t4","amount":null,"tags":[ "bag", "school", "book" ]} //0條數據 db.inventory.find( { amount: { $exists: false } } ) //所有的數據 db.inventory.find( { amount: { $exists: true } } )
$mod
語法: { field: { $mod: [ divisor, remainder ]} }
匹配字段值對(divisor)取模,值等於(remainder)的文檔。
//選擇集合中 amount 字段的值爲 4 的 0 次模數的所有文檔,例如 amount 值等於 16 的文檔 db.inventory.find( { amount: { $mod: [ 4, 0 ] } } )
有些情況下,我們可以使用$mod操作符替代使用求模表達式的$where操作符,因爲後者代價昂貴。
db.inventory.find( { $where: "this.amount % 4 == 0" } )
注意:返回結果怎麼不一樣。因爲有一條文檔的amount鍵值爲null,javascript中null進行數值轉換,會返回。所以該條文檔匹配$where操作符求模式了表達式。當文檔中字段值不存在null,就可以使用$mod替代$where的表達式.
$type
語法: { field: { $type: <BSON type> } }
選擇字段值爲指定的BSON數據類型的文檔.<BSON type>使用下面類型對應的編號:
類型 | 類型 | 編號 |
Double | 雙精度 | 1 |
String | 字符串 | 2 |
Object | 對象 | 3 |
Array | 數組 | 4 |
Binary data | 二進制對象 | 5 |
Object id | 對象id | 7 |
Boolean | 布爾值 | 8 |
Date | 日期 | 9 |
Null | 未定義 | 10 |
Regular Expression | 正則表達式 | 11 |
JavaScript |
JavaScript代碼 |
13 |
Symbol | 符號 | 14 |
JavaScript (with scope) | JavaScript代碼(帶範圍) | 15 |
32-bit integer | 32 位整數 | 16 |
Timestamp | 時間戳 | 17 |
64-bit integer | 64 位整數 | 18 |
Min key | 最小鍵 | 255 |
Max key | 最大鍵 | 127 |
如果文檔的鍵值是一個數組。那麼$type將對數組裏面的元素進行類型匹配而不是鍵值數組本身。
db.inventory.find( { tags: { $type : 4 } } ) //如果想檢查鍵值的類型是否爲數組類型,使用$where操作符 db.inventory.find( { $where : "Array.isArray(this.tags)" } )
下面例子展示了文檔中類型(包括MinKey 和MaxKey):
db.type.insert( {x : 3}); db.type.insert( {x : 2.9} ); db.type.insert( {x : new Date()} ); db.type.insert( {x : true } ); db.type.insert( {x : MaxKey } ) db.type.insert( {x : MinKey } ) > db.type.find() { "_id" : ObjectId("5185f9cfa1adf7d5f458505e"), "x" : 3 } { "_id" : ObjectId("5185f9cfa1adf7d5f458505f"), "x" : 2.9 } { "_id" : ObjectId("5185f9cfa1adf7d5f4585060"), "x" : ISODate("2013-05-05T06:18: 55.751Z") } { "_id" : ObjectId("5185f9cfa1adf7d5f4585061"), "x" : true } { "_id" : ObjectId("5185f9cfa1adf7d5f4585062"), "x" : { "$maxKey" : 1 } } { "_id" : ObjectId("5185f9d0a1adf7d5f4585063"), "x" : { "$minKey" : 1 } }
要查詢的字段值爲MinKey,使用下面的語法:
db.collection_name.find( { field: { $type: -1 } } )
JavaScript查詢操作符 JavaScript Query Operators
$regex
$regex操作符查詢中可以對字符串的執行正則匹配。 MongoDB使用Perl兼容的正則表達式(PCRE)庫來匹配正則表達式.
可以使用正則表達式對象或者$regex操作符.
//查詢name鍵值以“4”結尾的文檔 db.inventory.find( { name: /.4/i } ); db.inventory.find( { name: { $regex: '.4', $options: 'i' } } );
$options ($regex 提供四個選項標誌)
- i 如果設置了這個修飾符,模式中的字母會進行大小寫不敏感匹配。
- m 默認情況下,PCRE 認爲目標字符串是由單行字符組成的(然而實際上它可能會包含多行).如果目標字符串 中沒有 "\n"字符,或者模式中沒有出現“行首”/“行末”字符,設置這個修飾符不產生任何影響。
- s 如果設置了這個修飾符,模式中的點號元字符匹配所有字符,包含換行符。如果沒有這個修飾符,點號不匹配換行符。
- x 如果設置了這個修飾符,模式中的沒有經過轉義的或不在字符類中的空白數據字符總會被忽略,並且位於一個未轉義的字符類外部的#字符和下一個換行符之間的字符也被忽略。 這個修飾符使被編譯模式中可以包含註釋。 注意:這僅用於數據字符。 空白字符 還是不能在模式的特殊字符序列中出現,比如序列 。
注:JavaScript只提供了i和m選項,x和s選項必須使用$regex操作符。
$where
$where操作符功能強大而且靈活,他可以使用任意的JavaScript作爲查詢的一部分,包含JavaScript表達式的字符串或者JavaScript函數。
最典型的應用就是比較文檔中的兩個鍵的值是否相等.
//插入兩條數據 db.fruit.insert({"apple":1, "banana": 4, "peach" : 4}) db.fruit.insert({"apple":3, "banana": 3, "peach" : 4})
查找出banana等於peach鍵值的文檔(4種方法):
//字符串形式 db.fruit.find( { $where: "this.banana == this.peach" } ) db.fruit.find( { $where: "obj.banana == obj.peach" } ) //函數形式 db.fruit.find( { $where: function() { return (this.banana == this.peach) } } ) db.fruit.find( { $where: function() { return obj.banana == obj.peach; } } )
查出文檔中存在的兩個鍵的值相同的文檔。
>db.fruit.find({$where:function () { for (var current in this) { for (var other in this) { if (current != other && this[current] == this[other]) { return true; } } } return false; }});
不是非常必要時,一定要避免使用"$Where"査詢,因爲它們在速度上要比常規査詢慢很多。每個文檔都要從BSON轉換成JavaScript對象,然後通過"$where"的表達式來運行。同樣還不能利用索引。所以,只在走投無路時才考慮"$where"這種用法。