mongoose如何写条件查询?

假设我有以下查询:

post.getSpecificDateRangeJobs = function(queryData, callback) { var matchCriteria = queryData.matchCriteria; var currentDate = new Date(); var match = { expireDate: { $gte: new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate()) } }; if (queryData.matchCriteria !== "") { match = { expireDate: { $gte: new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate()) }, $text: { $search: matchCriteria } }; } var pipeline = [ { $match: match }, { $group: { _id: null, thirtyHourAgo: { $sum: { $cond: [ { $gte: [ "$publishDate", new Date(queryData.dateGroups.thirtyHourAgo) ] }, 1, 0 ] } }, fourtyEightHourAgo: { $sum: { $cond: [ { $gte: [ "$publishDate", new Date(queryData.dateGroups.fourtyHourAgo) ] }, 1, 0 ] } }, thirtyDaysAgo: { $sum: { $cond: [ { $lte: [ "$publishDate", new Date(queryData.dateGroups.oneMonthAgo) ] }, 1, 0 ] } } } } ]; var postsCollection = post.getDataSource().connector.collection( post.modelName ); postsCollection.aggregate(pipeline, function(err, groupByRecords) { if (err) { return callback("err"); } return callback(null, groupByRecords); }); }; 

我想要做的是:1-检查queryData.dateGroups.thirtyHourAgo存在和有价值,然后只在查询中添加相关的匹配条款(只有过去30小时的职位数)。 2-检查queryData.dateGroups.fourtyHourAgo存在,然后添加相关查询部分(过去30小时和过去48小时前的post数)。 3和queryData.dateGroups.oneMonthAgo (过去30小时,48小时和过去一个月的post数量)相同。

我需要像Mysql的东西,如果条件来检查variables是否存在,而不是空的,那么包含一个查询子句。 有没有可能做到这一点?

我的示例数据如下所示:

 /* 1 */ { "_id" : ObjectId("58d8bcf01caf4ebddb842855"), "vacancyNumber" : "123213", "position" : "dsfdasf", "number" : 3, "isPublished" : true, "publishDate" : ISODate("2017-03-11T00:00:00.000Z"), "expireDate" : ISODate("2017-05-10T00:00:00.000Z"), "keywords" : [ "dasfdsaf", "afdas", "fdasf", "dafd" ], "deleted" : false } /* 2 */ { "_id" : ObjectId("58e87ed516b51f33ded59eb3"), "vacancyNumber" : "213123", "position" : "Software Developer", "number" : 4, "isPublished" : true, "publishDate" : ISODate("2017-04-14T00:00:00.000Z"), "expireDate" : ISODate("2017-05-09T00:00:00.000Z"), "keywords" : [ "adfsadf", "dasfdsaf" ], "deleted" : false } /* 3 */ { "_id" : ObjectId("58eb5b01c21fbad780bc74b6"), "vacancyNumber" : "2432432", "position" : "Web Designer", "number" : 4, "isPublished" : true, "publishDate" : ISODate("2017-04-09T00:00:00.000Z"), "expireDate" : ISODate("2017-05-12T00:00:00.000Z"), "keywords" : [ "adsaf", "das", "fdafdas", "fdas" ], "deleted" : false } /* 4 */ { "_id" : ObjectId("590f04fbf97a5803636ec66b"), "vacancyNumber" : "4354", "position" : "Software Developer", "number" : 5, "isPublished" : true, "publishDate" : ISODate("2017-05-19T00:00:00.000Z"), "expireDate" : ISODate("2017-05-27T00:00:00.000Z"), "keywords" : [ "PHP", "MySql" ], "deleted" : false } 

假设我的应用程序界面中有三个链接:1-30小时前的post。 2- 48小时前发布。 3-最后一个月的职位。

现在,如果用户点击第一个链接,我应该控制到30小时前的post,但如果用户点击第二个链接,我应该准备我的查询来组织post30小时,也是48小时,如果用户点击第三我应该为他们做好准备。

我想要的东西是:

  var pipeline = [ { $match: match }, { $group: { _id: null, if (myVariable) { thirtyHourAgo: { ........ ........ } } if (mysecondVariable) { fortyEightHourAgo: { ........ ........ } } 

您可以使用JavaScript来根据您的查询参数dynamic创buildjson文档。

您更新的function将看起来像

 post.getSpecificDateRangeJobs = function(queryData, callback) { var matchCriteria = queryData.matchCriteria; var currentDate = new Date(); // match document var match = { "expireDate": { "$gte": currentDate } }; if (matchCriteria !== "") { match["$text"]: { "$search": matchCriteria } }; // group document var group = { _id: null }; // Logic to calculate hours difference between current date and publish date is less than 30 hours. if (queryData.dateGroups.thirtyHourAgo) { group["thirtyHourAgo"] = { "$sum": { "$cond": [{ "$lte": [{ "$divide": [{ "$subtract": [currentDate, "$publishDate"] }, 1000 * 60 * 60] }, 30] }, 1, 0 ] } }; } // Similarly add more grouping condition based on query params. var postsCollection = post.getDataSource().connector.collection( post.modelName ); // Use aggregate builder to create aggregation pipeline. postsCollection.aggregate() .match(match) .group(group) .exec(function(err, groupByRecords) { if (err) { return callback("err"); } return callback(null, groupByRecords); }); }; 

据我所知,我可以build议你下面的一般查询。 根据你的需要修改这个。

 db.getCollection('vacancy') .aggregate([{$match: { $and: [ {publishDate:{ $gte: new Date(2017, 4, 13) }} , {publishDate:{ $lte: new Date(2017, 4, 14) }} ]} }]) 

概要:

  • 使用匹配过滤结果。
  • 我们正在使用聚合pipe道,因此您可以在pipe道中添加更多聚合运算符
  • 使用$并执行逻辑“与”,因为我们想要在给定范围(如1天,2天或1个月)之间获取某些文档(根据您的要求更改date参数)