1. 程式人生 > >MongoDB邏輯操作符$or, $and,$not,$nor

MongoDB邏輯操作符$or, $and,$not,$nor

$or是一個邏輯or操作符操作在一個數據或者多個表示式並且需要選擇至少一個滿足條件的表示式,$or有至少以下表達式:

{ $or: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] }
考慮下面的例子:
db.inventory.find( { $or: [ { quantity: { $lt: 20 } }, { price: 10 } ] } )
上面的例子會查詢集合inventory中所有欄位quantity小於20或者price等於10的所有文件。

使用$or條件評估條款,MongoDB會掃描整個文件集合,如果所有的條件支援索引,MongoDB進行索引掃描,因此MongoDB使用索引執行$or表示式,$or中的所有表示式必須支援索引,否則的話MongoDB就會掃描整個集合。

當使用$or查詢並且使用索引時,每個$or的條件表示式都可以使用自己的索引,考慮下面的查詢:

db.inventory.find( { $or: [ { quantity: { $lt: 20 } }, { price: 10 } ] } )
支援上面的查詢你不需要建立一個符合索引,而是在欄位quantity上建立一個索引,在price上建立一個索引。
db.inventory.createIndex( { quantity: 1 } )
db.inventory.createIndex( { price: 1 } )
$or和sort()操作

當使用$or執行sort()查詢時,MongoDB可以使用支援$or查詢條件的索引。之前的版本不支援索引。

$or與$in

使用$or操作比較欄位的值是否等於某個值時可以使用$in替換$or操作;例如查詢集合inventory中欄位quantity的值等於20或者50的所有文件,使用$in操作:

db.inventory.find ( { quantity: { $in: [20, 50] } } )

$and邏輯表示式

語法:{$and:[{<expression1>},{<expression2>},...,{<expressionN>}]}

$and執行一個邏輯and操作在一個或者多個表示式上,並且查詢陣列中指定的所有表示式指定的文件document,$and使用短路求值,如果第一個表示式的結果是false,MongoDB將不會執行剩餘的表示式;

例如:and查詢指定同一個欄位的多個查詢條件

db.inventory.find( { $and: [ { price: { $ne: 1.99 } }, { price: { $exists: true } } ] } )
這個查詢會選擇集合inventory中的所有文件,條件是price不等於1.99並且price欄位存在;

以上查詢還可以使用隱式AND操作,如下:

db.inventory.find( { price: { $ne: 1.99, $exists: true } } )
AND查詢使用多個表示式指定相同的操作:
db.inventory.find( {
    $and : [
        { $or : [ { price : 0.99 }, { price : 1.99 } ] },
        { $or : [ { sale : true }, { qty : { $lt : 20 } } ] }
    ]
} )
以上欄位將會查詢price欄位值等於0.99或1.99並且sale欄位值為true或者qty小於20的所有文件;

使用隱式AND操作無法構建此查詢,因為它不止一次使用$or操作;

$not

語法:{ field: { $not: { <operator-expression> } } }

$not執行一個邏輯not操作在指定的表示式並查詢到不匹配表示式的文件,這包含不包括欄位的文件;

考慮如下操作:

db.inventory.find( { price: { $not: { $gt: 1.99 } } } )
此查詢將會查詢inventory集合中的文件,條件如下:price欄位小於等於1.99或者price不存在。

{ $not: { $gt: 1.99 } } 不同於$lte操作,{$lte:1.99}操作只會返回price欄位存在並且小於等於1.99的欄位。

記住$not操作符只會影響其他操作符不能獨立檢查欄位和文件,因此使用$not做邏輯析取和$ne操作測試欄位內容;

使用$not操作時考慮如下操作:

操作$not操作符和其它操作符一致但是會產生一些意想不到的結果,比如陣列之類的資料型別;

$not操作符不支援$regex正則表示式操作,使用//或者你的驅動介面代替,使用語言的正則表示式功能建立正則表示式物件;

考慮下面的例子使用模式匹配//:

db.inventory.find( { item: { $not: /^p.*/ } } )

此查詢將會查詢inventory集合中item欄位不是以p開頭的所有文件;

$nor

{ $nor: [ { <expression1> }, { <expression2> }, ...  { <expressionN> } ] }
考慮如下操作:
db.inventory.find( { $nor: [ { price: 1.99 }, { sale: true } ]  } )
查詢返回所有的文件,條件是:

包含欄位price值不等於1.99,包含欄位sale值不等於true,或者包含欄位price值不等於1.99,不包含欄位sale;或者不包含欄位price,包含欄位sale值不等於true;或者不包含欄位price,不包含欄位sale;

$nor額外比較

考慮入校操作:

db.inventory.find( { $nor: [ { price: 1.99 }, { qty: { $lt: 20 } }, { sale: true } ] }
inventory集合查詢所有的文件,條件如下:

欄位price不等於1.99,欄位qty不小於20,欄位sale不等於true;查詢的結果包含不存在的欄位;