需求是這樣的,我想要在一個集合中查詢出我需要的數據,約束條件中,這條數據的某個字段的值與自身的另外一個字段數據進行比較,滿足判斷等式的數據返回。
對應的SQL
select count(1) from hello where field1>field2
如果是老司機知道如何查詢的話,那就不用往下看了!
$where
在mongo3.6以下可以使用$where來達到目的,對應的寫法是
db.hello.find({$where:'this.field1>this.field2'})
db.hello.find({$where:function(){return this.field1>this.field2}})
需要注意的是$where本身不能使用count,會報錯 $whereis not allowed in this context,此處上下文不允許使用 $where,如果要達到統計多少條的目的,查詢出來之後,判斷長度,可以在options選項中設置只返回的_id以減少傳輸的數據量,提高查詢效率。
db.hello.find({$where:'this.field1>this.field2'},{_id:1})
db.hello.find({$where:function(){return this.field1>this.field2}},{_id:1})
一個非常大的問題是$where本身是逐條執行js語句,this就是遊標指向的當前行。那麼問題來了$where會不會走組合索引了?如果我在field1,field2上建立一個聯合索引,那麼使用$where會不會走索引了?個人猜測是會的
$expr
在mongo3.6版本以上,可以使用這個$expr。效率高於$where,原因在於不執行js語句。另外$expr不支持多鍵索引,mongo在建議索引時,如果你的字段類型是數組,那麼mongo會爲數組中的每個元素建立索引,這樣的索引稱爲多建索引。對於的具體查詢語句是
db.hello.find({$expr:{$gt:['$field1','$field2']}}).count()
使用$expr是支持count函數的。除此以外,還可以對字段帶條件的處理。$expr
db.supplies.find( {
$expr: {
$lt:[ {
$cond: {
if: { $gte: ["$qty", 100] },
then: { $divide: ["$price", 2] },
else: { $divide: ["$price", 4] }
}
},
5 ] }
} )