需求是这样的,我想要在一个集合中查询出我需要的数据,约束条件中,这条数据的某个字段的值与自身的另外一个字段数据进行比较,满足判断等式的数据返回。
对应的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 ] }
} )