2017-04-07 37 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關於速度優化,但仍然,正則表達式查詢不是很快。