web-dev-qa-db-ja.com

日時の月、日、年...でMongodbをクエリ

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

誰もこのクエリを行う方法を知っていますか?

40
kschaeffler

日付はタイムスタンプ形式で保存されます。特定の月に属するすべてのものが必要な場合は、月の始まりと終わりを照会します。

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/
48
DrColossos

日や月などの日付コンポーネントで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句と関数 詳細

28
RameshVel

クエリする必要があるので、月を独自のプロパティに保存するのはどうですか? $whereよりエレガントではありませんが、インデックスを作成できるため、パフォーマンスが向上する可能性があります。

10
RubyTuesdayDONO

特定の月に属するドキュメントを検索する場合は、次のようにクエリを実行してください。

// 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)}});
8
Ujjwal Ojha

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

ORを使用する

var month = 11,
    day = 17;
db.collection.aggregate([
    {
        "$redact": {
            "$cond": [
                { 
                    "$or": [ 
                        { "$eq": [ { "$month": "$createdAt" }, month ] },
                        { "$eq": [ { "$dayOfMonth": "$createdAt" }, day ] }
                    ] 
                },
                "$$KEEP",
                "$$Prune"
            ]
        }
    }
])

ANDを使用する

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を使用して、一致しないものをパイプラインから破棄します変数。

3
chridam

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は、他のすべてのフィールドを次の段階でプロジェクトに渡し、ドキュメントのすべての詳細を提供するために使用します。

必要に応じて上記のクエリを最適化できます。これは単に例を示したものです。日付集約演算子の詳細については、 リンク にアクセスしてください。

2
Puneet Singh

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