我有一个集合T
,有两个字段:Grade1
和Grade2
,我想选择条件为Grade1>的字段; Grade2
,我怎样才能像在MySQL中一样获得查询?
Select * from T Where Grade1 > Grade2
您可以使用$WHERE。 请注意,它将相当慢(必须对每个记录执行Javascript代码),因此如果可以,请与索引查询结合使用。
db.T.find( { $where: function() { return this.Grade1 > this.Grade2 } } );
或更紧凑:
db.T.find( { $where : "this.Grade1 > this.Grade2" } );
您可以使用$expr
,如最近回答中所述
您可以使用$expr(3.6mongo版本运算符)在常规查询中使用聚合函数。
比较查询运算符
与聚合比较运算符
。
常规查询:
db.T.find({$expr:{$gt:["$Grade1", "$Grade2"]}})
聚合查询:
db.T.aggregate({$match:{$expr:{$gt:["$Grade1", "$Grade2"]}}})
如果查询仅由$where
运算符组成,则可以只传入JavaScript表达式:
db.T.find("this.Grade1 > this.Grade2");
为了获得更高的性能,请运行一个具有$redact
管道的聚合操作,以筛选满足给定条件的文档。
$redact
管道合并了$project
和$match
的功能,以实现字段级编辑,在此管道中,它将使用$$keep
返回所有匹配条件的文档,并使用$$prune
变量从管道结果中删除那些不匹配的文档。
运行以下聚合操作比对大型集合使用$Where
更有效地筛选文档,因为它使用单个管道和本机MongoDB运算符,而不是使用$Where
的JavaScript计算,后者会降低查询速度:
db.T.aggregate([
{
"$redact": {
"$cond": [
{ "$gt": [ "$Grade1", "$Grade2" ] },
"$$KEEP",
"$$PRUNE"
]
}
}
])
这是合并两个管道$project
和$match
的更简化版本:
db.T.aggregate([
{
"$project": {
"isGrade1Greater": { "$cmp": [ "$Grade1", "$Grade2" ] },
"Grade1": 1,
"Grade2": 1,
"OtherFields": 1,
...
}
},
{ "$match": { "isGrade1Greater": 1 } }
])
对于MongoDB3.4及更新版本:
db.T.aggregate([
{
"$addFields": {
"isGrade1Greater": { "$cmp": [ "$Grade1", "$Grade2" ] }
}
},
{ "$match": { "isGrade1Greater": 1 } }
])