mongodbでISODateを使用した日付クエリが機能しないようです


189

最も基本的な日付クエリでさえ、MongoDBで機能するようには思えません。次のようなドキュメントの場合:

{
    "_id" : "foobar/201310",
    "ap" : "foobar",
    "dt" : ISODate("2013-10-01T00:00:00.000Z"),
    "tl" : 375439
}

そして、次のようなクエリ:

{ 
    "dt" : { 
        "$gte" : { 
            "$date" : "2013-10-01T00:00:00.000Z"
        }
    }
}

私は取得0の結果を実行するから。

db.mycollection.find({
  "dt" : { "$gte" : { "$date" : "2013-10-01T00:00:00.000Z"}}
})

これが機能しない理由は何ですか?

参考までに、このクエリはSpringのMongoTemplateによって生成されているため、最終的にMongoDBに送信されるクエリを直接制御することはできません。

(PS)

> db.version()
2.4.7

ありがとう!

回答:


312

けれども$dateの一部であるMongoDBの拡張JSONとし、それはあなたがデフォルトとして何を得るのですmongoexport私はあなたが本当にクエリの一部としてそれを使用することができるとは思いません。

$date以下のように正確に検索してみてください:

db.foo.find({dt: {"$date": "2012-01-01T15:00:00.000Z"}})

エラーが発生します:

error: { "$err" : "invalid operator: $date", "code" : 10068 }

これを試して:

db.mycollection.find({
    "dt" : {"$gte": new Date("2013-10-01T00:00:00.000Z")}
})

または(@ user3805045による以下のコメント):

db.mycollection.find({
    "dt" : {"$gte": ISODate("2013-10-01T00:00:00.000Z")}
})

ISODate時間なしで日付を比較することも必要になる場合があります(@MattMolnarで示されます)。

mongoシェルのデータ型によると両方とも同等であるはずです:

mongoシェルには、日付を文字列またはDateオブジェクトとして返すためのさまざまなメソッドが用意されています。

  • 現在の日付を文字列として返すDate()メソッド。
  • ISODate()ラッパーを使用してDateオブジェクトを返すnew Date()コンストラクター。
  • ISODate()ラッパーを使用してDateオブジェクトを返すISODate()コンストラクター。

を使用してISODate も、Dateオブジェクトが返されます

{"$date": "ISO-8601 string"}厳密なJSON表現が必要な場合に使用できます。考えられる1つの例は、Hadoopコネクタです。


3
うん。QuerySpringでオブジェクトをプリントアウトしたときに返ってきたものに私は驚いたと思います。クエリのシリアル化された形式は、mongoシェルに単にコピー/貼り付けできる有効なクエリであるとは限りません。mongoシェル自体は、いらいらします。犯人はここにある:grepcode.com/file/repo1.maven.org/maven2/org.mongodb/...
ジェイソン・ポライト

2
パーシャル(何時間)の日付を比較していないとき、私は切り替える必要があったnew Date('2016-03-09')ISODate('2016-03-09')。前者は$gteクエリに対して過去の日付を返します。
Matt Molnar

@MattMolnar指摘され、回答が帰属とともに更新されました。ありがとう。
zero323 2016年

92

MongoDBのクックブックページのコメント:

"dt" : 
{
    "$gte" : ISODate("2014-07-02T00:00:00Z"), 
    "$lt" : ISODate("2014-07-03T00:00:00Z") 
}

これでうまくいきました。完全なコンテキストでは、次のコマンドは、dt日付フィールドに2013-10-01(YYYY-MM-DD)Zulu の日付があるすべてのレコードを取得します。

db.mycollection.find({ "dt" : { "$gte" : ISODate("2013-10-01T00:00:00Z"), "$lt" : ISODate("2013-10-02T00:00:00Z") }})

1
「ISODate undefined」エラーが発生しました。私はこの問題を解決できませんでした。
Batuhan Akkaya

@BatuhanAkkaya pymongoを使用したpythonでは、datetime.datetimeと同等ISODateです。
jtbr


5

私はmongodbクライアントguiとしてrobomongoを使用しており、以下がうまくいきました

db.collectionName.find({"columnWithDateTime" : {
$lt:new ISODate("2016-02-28T00:00:00.000Z")}})

アプリ側では、nodejsベースのドライバーmongodb(v1.4.3)を使用しています。アプリケーションは、UIで日付ピッカーを使用して、YYYY-mm-ddのような日付を与えます。これに00:00:00のようなデフォルトの時刻が追加され、次に与えられます。new Date()MongoDBの基準オブジェクトに供給され、その後、コンストラクタと、私は、ドライバがISOの日付に日付を変換し、クエリが、その後所望の出力を動作し、与え、しかし同じだと思うnew Date()コンストラクタが同じため、ロボモンゴで同じ出力を仕事や表示されません。 robomongoを使用して基準オブジェクトをクロスチェックしたため、基準は奇妙です。

デフォルトのcli mongoshellはISODatenew Date()


1
ヒントをありがとう、RobomongoはMongo Compassより優れています
Alex

5

json strictモードでは、順序を維持する必要があります。

{
    "dt": {
        "$gte": {
            "$date": "2013-10-01T00:00:00.000Z"
        }
    }
}

mlab.comで検索クエリを定義するために機能した唯一のもの。


クエリの実行中にエラーが発生しました。理由:(invalid_operator)無効な演算子:$ date
saber tabatabaee yazdi 2018

2

MongoDBシェルで:

db.getCollection('sensorevents').find({from:{$gt: new ISODate('2015-08-30 16:50:24.481Z')}})

私のnodeJSコード(Mongooseを使用)

    SensorEvent.Model.find( {
        from: { $gt: new Date( SensorEventListener.lastSeenSensorFrom ) }
    } )

センサーイベントコレクションをクエリして、「from」フィールドが指定された日付より大きい値を返します


4
Stack Overflowへようこそ!質問への回答を投稿してください。「これが私の最初の投稿です」のような余分なものは投稿しないでください。Stack Overflowをメッセージボードではなく、Wikipediaと考えてください。
durron597

1

これは私のドキュメントです

"_id" : ObjectId("590173023c488e9a48e903d6"),
    "updatedAt" : ISODate("2017-04-27T04:26:42.709Z"),
    "createdAt" : ISODate("2017-04-27T04:26:42.709Z"),
    "flightId" : "590170f97cb84116075e2680",

 "_id" : ObjectId("590173023c488e9a48e903d6"),
        "updatedAt" : ISODate("2017-04-28T03:26:42.609Z"),
        "createdAt" : ISODate("2017-04-28T03:26:42.609Z"),
        "flightId" : "590170f97cb84116075e2680",

今、私は27日ごとのドキュメントを見つけたいので、これを使用しました...。

 > db.users.find({createdAt:{"$gte":ISODate("2017-04-27T00:00:00Z"),"$lt":ISODate("2017-04-28T00:00:00Z") }}).count()

result:1

これは私のために働いた。


0

これは、現在以下の値を検索するときに私にとってうまくいきました:

db.collectionName.find({ "dt": { "$lte" : new Date() + "" } });

0

で包みますnew Date()

{ "dt" : { "$lt" : new Date("2012-01-01T15:00:00.000Z") } }

0

古い質問ですが、まだ最初のgoogleヒットなので、ここに投稿して、もう一度簡単に見つけられるようにします...

Mongo 4.2とaggregate()の使用:

db.collection.aggregate(
    [
     { $match: { "end_time": { "$gt": ISODate("2020-01-01T00:00:00.000Z")  } } },
     { $project: {
          "end_day": { $dateFromParts: { 'year' : {$year:"$end_time"}, 'month' : {$month:"$end_time"}, 'day': {$dayOfMonth:"$end_time"}, 'hour' : 0  } }
     }}, 
     {$group:{
        _id:   "$end_day",
        "count":{$sum:1},
    }}
   ]
)

これは、groupby変数を日付として提供しますが、コンポーネント自体として扱う方が良い場合もあります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.