Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 构建动态$match:用于MongoDB聚合_Javascript_Node.js_Mongodb_Mongodb Query - Fatal编程技术网

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

Javascript 构建动态$match:用于MongoDB聚合,javascript,node.js,mongodb,mongodb-query,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

我正在尝试为我的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结构

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

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

更新!-现在就快拿到了,只是它把“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 } } } ] } },

您真正需要注意的第一件事是,您几乎不需要编写显式的
$和
语句。它有一个用法,但通常MongoDB查询中的所有表达式都是“AND”操作

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

var myMatch={
签入:签入,
结帐:结帐
};
if(请求正文属性ID){
myMatch[“property”]={“$in”:properties};
}
如果(请求正文状态==“活动”| |请求正文状态==“不允许”){
myMatch[“status”]={“$lte”:4};
}else if(请求主体hasOwnProperty('status')){
myMatch[“status”]={“$lte”:+req.body.status};
}
属性名称非常普通,因此您可以交替执行以下操作:

myMatch.property={“$in”:properties};
但这一切都归结为JavaScript对象的基本操作。在任何动态类型语言中都是一样的

然后你可以稍后再做:

{“$match”:myMatch}

这就完成了。

对于初学者来说,
checkin
checkout
似乎在每种情况下都始终存在,所以您可以创建一个基本对象,因为向JavaScript对象添加属性很简单。第二,你听说过吗?不管你做什么,停止用字符串来思考,学习一点对象操作。这里有一个小例子,它的结构要复杂得多,用两种不同的语言完成,但是概念基本上是一样的,我可以移动签入和签出,我还查看了
$project
管道的示例,但我不太确定我是否理解它。这有点让我头疼。但是看起来你可以把多个对象放到匹配中,而不仅仅是一个大字符串,对吗?!唉!好吧,那么至少请回答我这个问题。您的
签入
签出
都用括号括起来。为什么?这些还不是阵列吗?请说与
$in
一起使用的
属性
至少是一个数组。@NeilLunn-是的
属性
是一个数组
[“AAA”,“BBB]
等…我不确定你说的签入是什么意思。我应该改为这样做吗?
签入:{$gte:checkin}
?(对不起,我还在努力学习这些结构是如何工作的:-)啊哈哈!!!!!我明白了!!-所以你可以简单地把每个子句当作一个对象id,然后向其中添加参数。很简单-我不知道这是可能的。Niel如果这样做的话,我可以从我的控制器上剪下一千行:-)让我试试,然后回复你:)
req.body.hasOwnProperty['status']
我不知道的那一个-这是一种更优雅的请求对象属性的方法,而不仅仅是
!req.body.status
,它似乎总是给我带来问题。@torbenrudgaard注意到,我基本上只是按照你的想法构造字符串,但纠正了对对象的操作。我对最后的
做了更改>如果
条件为1。)在此处测试“status”属性的逻辑存在性,而不是返回值的“truthyness”,似乎更符合逻辑。2。)如果前面针对status的条件是数字(
“$lte”:4
),那么“status”属性也是符合逻辑的“应该是一个数值。除非您在其上运行了主体解析器,否则
req.body
项通常是字符串。所以
+req.body.status
转换。而不是
if(!req.body.propertyID)
我尝试了
if(req.body.hasOwnProperty['propertyID'])
,但它不起作用。req.body中的数据是:
{“propertyID”:[{u id:“PAP-720”,“u id:“ATL-D406”}]}
那么为什么
hasOwnProperty['propertyID']
返回未定义的?baah括号是错误的:-)
如果(req.body.hasOwnProperty('propertyID'))
有技巧:)
Mongoose: 
booking.aggregate([ 
{ '$match': { '$and': [ { myMatch: { checkin: { '$gte': 1473571600 }, checkout: { '$lte': 1596163600 }, property: { '$in': [ 'PAP-720', 'ATL-D406', 'WAT-606' ] }, status: { '$lte': 3 } } } ] } },