2017-04-07 39 views
1

我想为医院中的患者创建计划任务。患者将通过reg_date每月通知。猫鼬:按日期运行计划任务查询

我在我预定的工作中使用new Date().getDate()在上午8:00运行,向我的患者发送短信。同时,我一直在使用字符串格式日期在我的mongoDB中保存reg_date。这里是我的MongoDB文档的片段:

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

我已经奔冲浪的解决方案,但事实证明,什么都没有,所以我决定后我自己。这里就是我想要做的事:

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

E.g:我在做什么是“我想每一个病人谁在每月的17日登记并向他们发送短信”。

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

回答

1

对于这种类型有点复杂的查询,你需要使用聚合方法,而不是常规的查找方法。

$project这将帮助您投射您的区域,在这里我们创建一个新的临时区域day,仅有reg_date的日期。然后我们使用新的字段日查询并得到结果。

此临时字段day将永远不会添加到您的架构或模型中,它就像我们在SQL中创建的临时视图一样。

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

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场期间,你的进程预计...

+0

谢谢你的回应。但是,即使我有几个月或一年的时间,我仍然希望约翰再次出现。我能否用这个查询得到一个。 :) –

+0

安装了哪个版本的mongodb? –

+0

MongoDB shell版本:3.2.11 –

0

使用大于和小于

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]); 
    }; 
}); 
+0

谢谢你的回应。但是,即使我有几个月或一年的时间,我仍然希望约翰再次出现。我能否用这个查询得到一个。 :) –

1

随着reg_date字符串不能为一个月的日查询,因为只有它与ISODate一起工作。我建议您首先用脚本将所有文档中的字符串reg_date转换。

然后下面的查询应该工作

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]); 
    }; 
}) 
+0

您好Talha,你的答案看起来很有希望给我。我在mongoDB和mongoose ODM方面还是新手。你能否详细说明'$ project'部分?干杯。 –

+0

它用于聚合管道。官方定义很有帮助:“[project](https://docs.mongodb.com/manual/reference/operator/aggregation/project/#pipe._S_project)将包含请求字段的文档传递到管道。” –

0

由于reg_date存储为一个字符串,而不是日期/ ISODate,你只限于为可以运行什么样的查询(所以我同意在其他答案之一中的评论,你应该考虑把它们转换成适当的ISODate)。

考虑到要查询的条目的日期字符串与特定日子的日,你可以使用一个regular expression查询:

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

或者动态:

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 }) 

你还应该阅读this关于速度优化,但仍然,正则表达式查询不是很快。