Javascript 构建动态$match:用于MongoDB聚合
我正在尝试为我的MongoDB聚合构建一个动态的$match: 这就是我希望我能做的: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
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 } } } ] } },