私はmongodbを使用しており、このようにデータベースにdatetimeを保存しています
日付「17-11-2011 18:00」の場合:
date = datetime.datetime(2011, 11, 17, 18, 0)
db.mydatabase.mycollection.insert({"date" : date})
私はそのようなリクエストをしたいと思います
month = 11
db.mydatabase.mycollection.find({"date.month" : month})
または
day = 17
db.mydatabase.mycollection.find({"date.day" : day})
誰もこのクエリを行う方法を知っていますか?
日付はタイムスタンプ形式で保存されます。特定の月に属するすべてのものが必要な場合は、月の始まりと終わりを照会します。
var start = new Date(2010, 11, 1);
var end = new Date(2010, 11, 30);
db.posts.find({created_on: {$gte: start, $lt: end}});
//taken from http://cookbook.mongodb.org/patterns/date_range/
日や月などの日付コンポーネントでmongodbコレクションを直接クエリすることはできません。しかし、特別な$ whereJavaScript式を使用することで可能です
db.mydatabase.mycollection.find({$where : function() { return this.date.getMonth() == 11} })
または単に
db.mydatabase.mycollection.find({$where : 'return this.date.getMonth() == 11'})
(しかし、私は最初のものを好む)
日付の一部を取得するには、以下のシェルコマンドを確認してください
>date = ISODate("2011-09-25T10:12:34Z")
> date.getYear()
111
> date.getMonth()
8
> date.getdate()
25
編集:
他に選択肢がない場合にのみ、$ whereを使用します。パフォーマンスの問題があります。 @kamaradclimberと@dcrostaによる以下のコメントをチェックしてください。私はこの投稿を公開し、他の人々がそれについての事実を知るようにします。
リンクを確認してください クエリの$ where句と関数 詳細
クエリする必要があるので、月を独自のプロパティに保存するのはどうですか? $where
よりエレガントではありませんが、インデックスを作成できるため、パフォーマンスが向上する可能性があります。
特定の月に属するドキュメントを検索する場合は、次のようにクエリを実行してください。
// Anything greater than this month and less than the next month
db.posts.find({created_on: {$gte: new Date(2015, 6, 1), $lt: new Date(2015, 7, 1)}});
可能な限り以下のようなクラッカーを避けます。
// This may not find document with date as the last date of the month
db.posts.find({created_on: {$gte: new Date(2015, 6, 1), $lt: new Date(2015, 6, 30)}});
// don't do this too
db.posts.find({created_on: {$gte: new Date(2015, 6, 1), $lte: new Date(2015, 6, 30)}});
aggregate()
を受け取る集約操作を実行できます$redact
条件式で Date Aggregation Operators を使用するパイプライン:
var month = 11;
db.collection.aggregate([
{
"$redact": {
"$cond": [
{ "$eq": [ { "$month": "$createdAt" }, month ] },
"$$KEEP",
"$$Prune"
]
}
}
])
他のリクエストの場合
var day = 17;
db.collection.aggregate([
{
"$redact": {
"$cond": [
{ "$eq": [ { "$dayOfMonth": "$createdAt" }, day ] },
"$$KEEP",
"$$Prune"
]
}
}
])
var month = 11,
day = 17;
db.collection.aggregate([
{
"$redact": {
"$cond": [
{
"$or": [
{ "$eq": [ { "$month": "$createdAt" }, month ] },
{ "$eq": [ { "$dayOfMonth": "$createdAt" }, day ] }
]
},
"$$KEEP",
"$$Prune"
]
}
}
])
var month = 11,
day = 17;
db.collection.aggregate([
{
"$redact": {
"$cond": [
{
"$and": [
{ "$eq": [ { "$month": "$createdAt" }, month ] },
{ "$eq": [ { "$dayOfMonth": "$createdAt" }, day ] }
]
},
"$$KEEP",
"$$Prune"
]
}
}
])
$redact
演算子には、$project
および$match
パイプラインであり、を使用して条件に一致するすべてのドキュメントを返します$$KEEP
および$$Prune
を使用して、一致しないものをパイプラインから破棄します変数。
Date Aggregation Operatorsによって、日付の月、日、年などでレコードを検索できます。たとえば、$ dayOfYear、$ dayOfWeek、$ month、$ yearなど.
例として、2016年4月に作成されたすべての注文が必要な場合、以下のクエリを使用できます。
db.getCollection('orders').aggregate(
[
{
$project:
{
doc: "$$ROOT",
year: { $year: "$created" },
month: { $month: "$created" },
day: { $dayOfMonth: "$created" }
}
},
{ $match : { "month" : 4, "year": 2016 } }
]
)
ここで作成されるのは、ドキュメント内の日付タイプフィールドです。$$ ROOTは、他のすべてのフィールドを次の段階でプロジェクトに渡し、ドキュメントのすべての詳細を提供するために使用します。
必要に応じて上記のクエリを最適化できます。これは単に例を示したものです。日付集約演算子の詳細については、 リンク にアクセスしてください。
MongoDB_DataObject wrapperを使用して、以下のようなクエリを実行できます。
$model = new MongoDB_DataObject('orders');
$model->whereAdd('MONTH(created) = 4 AND YEAR(created) = 2016');
$model->find();
while ($model->fetch()) {
var_dump($model);
}
または、同様に、直接クエリ文字列を使用します。
$model = new MongoDB_DataObject();
$model->query('SELECT * FROM orders WHERE MONTH(created) = 4 AND YEAR(created) = 2016');
while ($model->fetch()) {
var_dump($model);
}