提问者:小点点

比较2个字段时的MongoDb查询条件


我有一个集合T,有两个字段:Grade1Grade2,我想选择条件为Grade1>的字段; Grade2,我怎样才能像在MySQL中一样获得查询?

Select * from T Where Grade1 > Grade2

共3个答案

匿名用户

您可以使用$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 } }
])