构建动态$ match:用于MongoDB聚合

时间:2017-05-22 09:34:40

标签: javascript node.js mongodb mongodb-query

我正在尝试为我的MongoDB聚合构建动态$ match:

这就是我希望我能做到的:

var matchStr = "";
if (req.body.propertyID) {
    matchStr += "property: { $in: properties },"
}
if (req.body.status=="ACTIVE" || req.body.status=="NOPAY") {
    matchStr += "status : {$lte: 4},"
} else if (req.body.status) {
    matchStr += "status : {$lte: req.body.status},"
}
matchStr += "checkin : {$gte: (checkin)}, checkout: {$lte: (checkout)}"

这就是我最终要做的事情:

它如此凌乱,现在我必须在$ match中添加更多的语句,这将给我更大的结构。

必须有更好的方法来做到这一点!

我希望有人知道如何在没有“if hell :)”的情况下动态构建这些内容。

if (req.body.propertyID & req.body.status=="ALL") {
    var matchStr = { 
        $match: {
            $and: 
            [{ 
                property: { $in: properties },
                checkin : {$gte: (checkin)}, 
                checkout: {$lte: (checkout)}    
            }]
        }
    }
} else if (!req.body.propertyID & !req.body.status) {
    var matchStr = { 
        $match: {
            $and: 
            [{ 
                checkin : {$gte: (checkin)}, 
                checkout: {$lte: (checkout)}    
            }]
        }
    }
} else if ((req.body.status=="ACTIVE" || req.body.status=="NOPAY")) {
    if (req.body.propertyID) { 
        var matchStr = { 
            $match: {
                $and: 
                [{ 
                    property: { $in: properties },
                    status : {$lte: 4}, 
                    checkin : {$gte: (checkin)}, 
                    checkout: {$lte: (checkout)}    
                }]
            }
        }
    } else {
        var matchStr = { 
            $match: {
                $and: 
                [{ 
                    status : {$lte: 4}, 
                    checkin : {$gte: (checkin)}, 
                    checkout: {$lte: (checkout)}    
                }]
            }
        }
    }
} else {
    if (req.body.propertyID) { 
        var matchStr = { 
            $match: {
                $and: 
                [{ 
                    property: { $in: properties },
                    status : {$lte: req.body.status}, 
                    checkin : {$gte: (checkin)}, 
                    checkout: {$lte: (checkout)}    
                }]
            }
        }
    } else {
        var matchStr = { 
            $match: {
                $and: 
                [{ 
                    status : {$lte: req.body.status}, 
                    checkin : {$gte: (checkin)}, 
                    checkout: {$lte: (checkout)}    
                }]
            }
        }
    }
}

UPDATE! - 几乎得到了它,除了它将“myMatch”放在mongoDB语句中。

这是新代码:

var myMatch = {
    checkin: {$gte: checkin},
    checkout: {$lte: checkout}
};

if (req.body.hasOwnProperty('propertyID')) {
    var properties = req.body.propertyID.map(function (obj) {
        return obj._id;
    });
    console.log("properties: " + properties); 
    myMatch["property"] = { "$in": properties };
}
if (req.body.status=="ACTIVE" || req.body.status=="NOPAY") {
    myMatch["status"] = { "$lte": 4 };
} else if (req.body.hasOwnProperty('status')) {
    myMatch["status"] = { "$lte": +req.body.status };
}

这是该结构的控制台日志:

myMatch: {
    "checkin": {
        "$gte": 1473571600
    },
    "checkout": {
        "$lte": 1596163600
    },
    "property": {
        "$in": [
            "PAP-720",
            "ATL-D406",
            "WAT-606"
        ]
    },
    "status": {
        "$lte": 3
    }
}

这是我注入myMatch对象的地方:

    bookingTable.aggregate([
        {
            $match: {
                $and: 
                [{ 
                    myMatch
                }]
            }
        },

这是最后的mongodb声明:

Mongoose: 
booking.aggregate([ 
{ '$match': { '$and': [ { myMatch: { checkin: { '$gte': 1473571600 }, checkout: { '$lte': 1596163600 }, property: { '$in': [ 'PAP-720', 'ATL-D406', 'WAT-606' ] }, status: { '$lte': 3 } } } ] } },

1 个答案:

答案 0 :(得分:1)

首先,您需要注意的是,您几乎不需要编写明确的$and语句。它有一个用法,但MongoDB查询中通常所有表达式已经是" AND"操作

接下来的事情是解决方案看起来非常熟悉:

var myMatch = {
    checkin: checkin,
    checkout: checkout
};

if (req.body.propertyID) {
    myMatch["property"] = { "$in": properties };
}
if (req.body.status=="ACTIVE" || req.body.status=="NOPAY") {
    myMatch["status"] = { "$lte": 4 };
} else if (req.body.hasOwnProperty('status')) {
    myMatch["status"] = { "$lte": +req.body.status };
}

属性名称非常正常,因此您可以选择:

    myMatch.property = { "$in": properties };

但这一切都归结为JavaScript对象的基本操作。在任何动态类型语言中它都几乎相同。

然后你可以稍后再做:

{ "$match": myMatch }

完成了。