Mongoose:按date运行计划任务查询

我想为医院的病人创造一个预定的工作。 患者将在每个月的reg_date

我在早上8点使用new Date().getDate()在我的计划任务中运行,向我的患者发送短信。 同时,我一直使用string格式date来保存我的mongoDB中的reg_date。 这里是我的mongoDB文档的片段:

 { customer: "John", reg_date: "2017-02-17T16:39:26.969Z" } 

我一直在冲浪的解决scheme,但什么都没有,所以我决定张贴自己。 这是我想要做的:

 customer.find({"reg_date.getDate()" : new Date(2017, 03, 17).getDate()}) .then(function(data) { for (var key in data.length) { sendTheSMS(key[data]); }; }); 

例如:我正在做的是“我想让每个在本月17日注册的病人都给他们发短信”。

任何帮助将不胜感激。 :d

对于这种types的位复杂查询,您需要使用聚合方法而不是常规查找方法。

$project这将帮助您投影您的领域,在这里我们正在创build一个新的临时领域day只有date的reg_date 。 然后我们查询使用新的一天,我们得到的结果。

这个temp字段将永远不会添加到您的模式或模型中,就像我们在SQL中创build的临时视图一样。

在这里,我只预测客户和一天,但请投影结果中所有必要的领域。

 function getCustomerList(day, callback){ customer.aggregate([ { $project:{ "customer": "$customer", //repeat the same for all field you want in result "reg_date": "$reg_date", "day":{$dayOfMonth:"$reg_date"} //put day of month in 'day' } }, { $match:{ "day": day //now match the day with the incoming day value } }, ], function(err, result){ callback(err, result); }) } getCustomerList(17, function(err, result){ // call the function like this with date you want // Process the err & result here }); 

结果会是这样的

 [{ "_id" : ObjectId("571f2da8ca97eb10163e6e17"), "customer" : "John", "reg_date" : ISODate("2016-04-17T08:58:16.414Z"), "day" : 17 }, { "_id" : ObjectId("571f2da8ca97eb10163e6e17"), "customer" : "Prasanth", "reg_date" : ISODate("2016-04-17T08:58:16.414Z"), "day" : 17 }] 

忽略您的过程中投射的day字段…

在stringreg_date中,您不能查询月份的date,因为它仅适用于ISODate 。 我build议你首先用脚本将所有文档中的reg_datestring转换。

然后下面的查询应该工作

 customer.aggregate([ { $project:{ "document": "$$ROOT", //to get the whole document "day":{$dayOfMonth:"$date"} //put day of month in 'day' } }, { $match:{ "day": 17 //match 17 } }, ], function(data) { for (var key in data.length) { sendTheSMS(key[data]); }; }) 

使用大于和小于

 var previousDate =new Date(2017, 1, 16); //month starts with 0 var nextDate=new Date(2017, 1, 18); customer.find({reg_date : { $gt:previousDate,$lt:nextDate}}) .then(function(data) { for (var key in data.length) { sendTheSMS(key[data]); }; }); 

由于reg_date是以string的forms存储的,而不是Date / ISODate,因此您可以运行的查询types有限(所以我同意其他答案中的注释,您应该考虑将其转换为适当的ISODate )。

考虑到要查询datestring以查找特定date的条目,可以使用正则expression式查询:

 customer.find({ reg_date : /-17T/ }) 

或者,dynamic地:

 let today = new Date(); let dom = ('00' + today.getDate()).slice(-2); // zero-pad day of month let re = new RegExp('-' + dom + 'T'); customer.find({ reg_date : re }) 

你也应该阅读这个速度优化,但仍然,正则expression式查询不是很快。