如何动态构建mongodb查询

时间:2017-02-18 13:17:16

标签: mongodb mongodb-query aggregation-framework

我在mongodb聚合中有一个匹配表达式。匹配中包含3个字段,但它们并不总是包含数据。如果字段不为空,我只想在匹配中包含字段。

如果所有字段都有数据,这就是匹配的样子,但是例如,如果用于studentGradeLevels的数组是空的,那么我不想包含它,或者我希望查询仍然返回数据忽略空参数。

$match: {
    "school._id": "7011",
    "studentGradeLevels": { $in: ["09", "10", "11", "12"] },
    "contentArea": {
        $in: [
            "English 1"
        ]
    }
}

有没有办法动态构建匹配,以便我只根据它们是否为空而包含我想要的字段,或者在查询中执行某些操作,以便忽略空的参数。

2 个答案:

答案 0 :(得分:2)

数组不为空时可以使用$in,数组为空时可以使用$nin,这样就不会考虑匹配字段($nin : []):

function buildMatch(arr) {
    var matcher = {};
    if (arr.length == 0)
        matcher["$nin"] = arr;
    else
        matcher["$in"] = arr;
    return matcher;
}

var grades = ["09", "10", "11", "12"];
var areas = [ "English 2" ];

var gradeMatch = buildMatch(grades);
var areaMatch = buildMatch(areas);

db.students.aggregate([{
    $match: {
        "school._id": "7011",
        "studentGradeLevels": gradeMatch,
        "contentArea": areaMatch
    }
}])

答案 1 :(得分:0)

变体:检查字段是否存在,如果是,请更改为特殊值,例如_并将其添加到$in列表中:

db.foo.aggregate([
{$project: {"studentGradeLevels":{$ifNull: ["$studentGradeLevels","_"]},
            "contentArea":{$ifNull: ["$contentArea","_"]}
}}
,{$match: {
        "studentGradeLevels": { $in: ["_", "09", "10", "11", "12"] },
        "contentArea": { $in: [ "_", "English 1" ]  }
}}
              ]);