Kueri tanggal dengan ISODate di mongodb tampaknya tidak berfungsi

189

Saya sepertinya tidak bisa mendapatkan bahkan query tanggal paling dasar untuk bekerja di MongoDB. Dengan dokumen yang terlihat seperti ini:

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

Dan permintaan yang terlihat seperti ini:

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

Saya mendapatkan 0 hasil dari mengeksekusi:

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

Adakah yang tahu mengapa ini tidak berhasil?

Untuk referensi, kueri ini sedang diproduksi oleh Spring's MongoTemplate jadi saya tidak punya kendali langsung atas kueri yang akhirnya dikirim ke MongoDB.

(PS)

> db.version()
2.4.7

Terima kasih!

Jason Polites
sumber

Jawaban:

312

Meskipun $datemerupakan bagian dari MongoDB Extended JSON dan itulah yang Anda dapatkan sebagai default dengan mongoexportSaya tidak berpikir Anda benar-benar dapat menggunakannya sebagai bagian dari permintaan.

Jika coba cari yang tepat dengan $dateseperti di bawah ini:

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

Anda akan mendapatkan kesalahan:

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

Coba ini:

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

atau (mengikuti komentar oleh @ user3805045 ):

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

ISODatemungkin juga diperlukan untuk membandingkan tanggal tanpa waktu (dicatat oleh @MattMolnar ).

Menurut Tipe Data di mongo Shell keduanya harus sama:

Shell mongo menyediakan berbagai metode untuk mengembalikan tanggal, baik sebagai string atau sebagai objek Date:

  • Metode Date () yang mengembalikan tanggal saat ini sebagai string.
  • konstruktor Date () baru yang mengembalikan objek Date menggunakan wrapper ISODate ().
  • Konstruktor ISODate () yang mengembalikan objek Date menggunakan wrapper ISODate ().

dan menggunakan ISODate masih harus mengembalikan objek Date .

{"$date": "ISO-8601 string"}dapat digunakan ketika representasi JSON ketat diperlukan. Salah satu contoh yang mungkin adalah konektor Hadoop.

nol323
sumber
3
Ya. Saya pikir saya terlempar oleh apa yang dikembalikan ketika Anda mencetak Queryobjek di Musim Semi. Bentuk kueri berseri tidak selalu merupakan kueri yang valid yang bisa Anda salin / tempelkan ke mongo shell, yang dengan sendirinya agak membuat frustrasi. Pelakunya ada di sini: grepcode.com/file/repo1.maven.org/maven2/org.mongodb/…
Jason Polites
2
Ketika membandingkan tanggal parsial (tidak ada waktu), saya harus beralih dari new Date('2016-03-09')ke ISODate('2016-03-09'). Yang pertama akan mengembalikan tanggal di masa lalu untuk $gtepermintaan.
Matt Molnar
@MattMolnar Tercatat, dan memperbarui jawabannya dengan atribusi. Terima kasih.
zero323
92

Dari komentar halaman buku resep MongoDB :

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

Ini berhasil untuk saya. Dalam konteks penuh, perintah berikut ini membuat setiap catatan di mana dtbidang tanggal memiliki tanggal pada 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") }})
Steve HHH
sumber
1
Saya mendapat kesalahan "ISODate undefined". Saya tidak bisa menyelesaikan masalah ini.
Batuhan Akkaya
@BatuhanAkkaya Dalam python dengan pymongo, datetime.datetimesama dengan ISODate.
jtbr
12

Coba ini:

{ "dt" : { "$gte" : ISODate("2013-10-01") } }
Jabba
sumber
5

Saya menggunakan robomongo sebagai gui mongodb klien dan di bawah ini bekerja untuk saya

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

Di sisi aplikasi saya menggunakan mongodb driver berbasis nodejs (v1.4.3), aplikasi menggunakan datepicker di ui yang memberikan tanggal seperti YYYY-mm-dd, ini kemudian ditambahkan dengan waktu default seperti 00:00:00 dan kemudian diberikan ke new Date()konstruktor dan kemudian dipasok ke objek kriteria mongodb, saya pikir pengemudi mengubah tanggal menjadi tanggal ISO dan permintaan kemudian bekerja dan memberikan output yang diinginkan, namun new Date()konstruktor yang sama tidak berfungsi atau menampilkan output yang sama pada robo mongo, untuk hal yang sama kriteria, yang aneh, karena saya menggunakan robomongo untuk memeriksa objek kriteria saya.

Sedangkan cli mongoshell default berfungsi baik dengan keduanya ISODatedannew Date()

siddharthrc
sumber
1
Terima kasih atas tipnya, Robomongo jauh lebih baik daripada Kompas Mongo
Alex
5

Dalam mode ketat json, Anda harus menjaga urutan:

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

Hanya hal yang berfungsi untuk menentukan kueri penelusuran saya di mlab.com.

3vangelos
sumber
Kesalahan saat menjalankan kueri. Alasan: (invalid_operator) Operator tidak valid: $ date
saber tabatabaee yazdi
2

Dalam shell MongoDB:

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

Dalam kode nodeJS saya (menggunakan Mongoose)

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

Saya menanyakan koleksi acara sensor saya untuk mengembalikan nilai di mana bidang 'dari' lebih besar dari tanggal yang diberikan

lewma
sumber
4
Selamat Datang di Stack Overflow! Silakan saja kirim jawaban untuk pertanyaan, dan bukan hal-hal tambahan seperti "Ini adalah posting pertama saya". Pikirkan Stack Overflow sebagai Wikipedia, bukan papan pesan.
durron597
1

ini dokumen saya

"_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",

sekarang saya ingin menemukan setiap dokumen tanggal 27. jadi saya menggunakan ini ....

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

result:1

ini bekerja untuk saya.

pembuat kode
sumber
0

Ini berfungsi untuk saya saat mencari nilai kurang dari atau sama dengan sekarang:

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

Bungkus dengan new Date():

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

Pertanyaan lama, tetapi masih hit google pertama, jadi saya posting di sini jadi saya menemukannya lagi dengan lebih mudah ...

Menggunakan Mongo 4.2 dan agregat ():

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

Yang ini memberi Anda variabel groupby sebagai tanggal, kadang-kadang lebih baik ditangani sebagai komponen itu sendiri.

A. Rabus
sumber