特定の日付を照会することは可能ですか?
Mongo Cookbookで、範囲に対してそれができることがわかりました 日付範囲のクエリ そのように:
db.posts.find({"created_on": {"$gte": start, "$lt": end}})
しかし、特定の日付は可能ですか?これは機能しません:
db.posts.find({"created_on": new Date(2012, 7, 14) })
DBに保存した日付に時間がない場合(年、月、日のみ)に機能します。
保存した日付はnew Date()
であり、これには時間コンポーネントが含まれている可能性があります。これらの時間を照会するには、1日のすべての瞬間を含む日付範囲を作成する必要があります。
db.posts.find( //query today up to tonight
{"created_on": {"$gte": new Date(2012, 7, 14), "$lt": new Date(2012, 7, 15)}})
const moment = require('moment')
const today = moment().startOf('day')
MyModel.find({
createdAt: {
$gte: today.toDate(),
$lte: moment(today).endOf('day').toDate()
}
})
重要: すべてのモーメントは変更可能 !
tomorrow = today.add(1, 'days')
は、today
も変更するため機能しません。 moment(today)
を呼び出すと、暗黙的にtoday
のクローンを作成することでその問題を解決します。
やってみました:
db.posts.find({"created_on": {"$gte": new Date(2012, 7, 14), "$lt": new Date(2012, 7, 15)}})
遭遇する問題は、日付がタイムスタンプとしてMongoに保存されることです。したがって、日付を一致させるには、タイムスタンプと一致するように日付を要求します。あなたの場合、私はあなたが一日(すなわち、特定の日付の00:00から23:59まで)にマッチしようとしていると思います。日付が時刻なしで保存されている場合は、大丈夫です。それ以外の場合、gteが機能しない場合は、同じ日の時間範囲(たとえば、start = 00:00、end = 23:59)として日付を指定してみてください。
APIメソッドに次のアプローチを使用して、特定の日の結果を取得できます。
# [HTTP GET]
getMeals: (req, res) ->
options = {}
# eg. api/v1/meals?date=Tue+Jan+13+2015+00%3A00%3A00+GMT%2B0100+(CET)
if req.query.date?
date = new Date req.query.date
date.setHours 0, 0, 0, 0
endDate = new Date date
endDate.setHours 23, 59, 59, 59
options.date =
$lt: endDate
$gte: date
Meal.find options, (err, meals) ->
if err or not meals
handleError err, meals, res
else
res.json createJSON meals, null, 'meals'
ええ、Dateオブジェクトは日付と時刻を反映するため、日付値と比較するだけでは機能しません。
$ where 演算子を使用して、Javascriptブール式でより複雑な条件を表現できます:)
db.posts.find({ '$where': 'this.created_on.toJSON().slice(0, 10) == "2012-07-14"' })
created_on
は日時フィールドで、2012-07-14
は指定された日付です。
日付は正確にYYYY-MM-DD形式である必要があります。
注:$where
を控えめに使用すると、パフォーマンスに影響します。
データベース内の重複データに関連する問題があり、日付フィールドには複数の値があり、その値は1になります。問題を解決する方法を参照用に追加すると思いました。
数値の「値」フィールドと日付の「日付」フィールドを持つ「データ」というコレクションがあります。べき等であると考えていたプロセスがありましたが、2回目の実行で1日あたり2 x値を追加することになりました。
{ "_id" : "1", "type":"x", "value":1.23, date : ISODate("2013-05-21T08:00:00Z")}
{ "_id" : "2", "type":"x", "value":1.23, date : ISODate("2013-05-21T17:00:00Z")}
2つのレコードのうち1つしか必要ないため、javascriptを使用してdbをクリーンアップする必要がありました。最初のアプローチは、結果を反復処理し、午前6時から午前11時までの時間にフィールドを削除することでした(重複はすべて午前中でした)が、実装中に変更を加えました。修正に使用したスクリプトは次のとおりです。
var data = db.data.find({"type" : "x"})
var found = [];
while (data.hasNext()){
var datum = data.next();
var rdate = datum.date;
// instead of the next set of conditions, we could have just used rdate.getHour() and checked if it was in the morning, but this approach was slightly better...
if (typeof found[rdate.getDate()+"-"+rdate.getMonth() + "-" + rdate.getFullYear()] !== "undefined") {
if (datum.value != found[rdate.getDate()+"-"+rdate.getMonth() + "-" + rdate.getFullYear()]) {
print("DISCREPENCY!!!: " + datum._id + " for date " + datum.date);
}
else {
print("Removing " + datum._id);
db.data.remove({ "_id": datum._id});
}
}
else {
found[rdate.getDate()+"-"+rdate.getMonth() + "-" + rdate.getFullYear()] = datum.value;
}
}
そしてmongo thedatabase fixer_script.js
でそれを実行しました