Truy vấn ngày với ISODate trong mongodb dường như không hoạt động


189

Tôi dường như không thể có được ngay cả truy vấn ngày cơ bản nhất để hoạt động trong MongoDB. Với một tài liệu trông giống như thế này:

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

Và một truy vấn trông như thế này:

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

Tôi nhận được 0 kết quả từ việc thực hiện:

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

Bất cứ ý tưởng tại sao điều này không làm việc?

Để tham khảo, truy vấn này được sản xuất bởi MongoTemplate của Spring, vì vậy tôi không có quyền kiểm soát trực tiếp đối với truy vấn cuối cùng được gửi đến MongoDB.

(PS)

> db.version()
2.4.7

Cảm ơn!

Câu trả lời:


312

Mặc dù $datelà một phần của MongoDB Extended JSON và đó là những gì bạn nhận được theo mặc định với mongoexporttôi không nghĩ bạn thực sự có thể sử dụng nó như một phần của truy vấn.

Nếu thử tìm kiếm chính xác $datenhư dưới đây:

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

bạn sẽ gặp lỗi:

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

Thử cái này:

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

hoặc (nhận xét sau bởi @ user3805045 ):

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

ISODatecũng có thể được yêu cầu để so sánh ngày mà không có thời gian (được ghi chú bởi @MattMolnar ).

Theo Kiểu dữ liệu trong Shell mongo cả hai phải tương đương nhau:

Shell mongo cung cấp các phương thức khác nhau để trả về ngày, dưới dạng chuỗi hoặc là đối tượng Ngày:

  • Phương thức Date () trả về ngày hiện tại dưới dạng chuỗi.
  • hàm tạo Date () mới trả về một đối tượng Date bằng cách sử dụng trình bao bọc ISODate ().
  • Hàm tạo ISODate () trả về một đối tượng Date bằng cách sử dụng trình bao bọc ISODate ().

và sử dụng ISODate vẫn nên trả về một đối tượng Date .

{"$date": "ISO-8601 string"}có thể được sử dụng khi yêu cầu đại diện JSON nghiêm ngặt. Một ví dụ có thể là kết nối Hadoop.


3
Vâng. Tôi nghĩ rằng tôi đã bị loại bỏ bởi những gì được trả lại khi bạn in ra Queryđối tượng trong Spring. Dạng truy vấn được xê-ri hóa không nhất thiết là một truy vấn hợp lệ mà bạn chỉ có thể sao chép / dán vào một vỏ mongo, bản thân nó là một loại bực bội. Thủ phạm là đây: grepcode.com/file/repo1.maven.org/maven2/org.mongodb/ chủ
Jason Polites

2
Khi so sánh một ngày (không có thời gian), tôi phải chuyển từ new Date('2016-03-09')sang ISODate('2016-03-09'). Các cựu sẽ trả lại ngày trong quá khứ cho một $gtetruy vấn.
Matt Molnar

@MattMolnar Lưu ý và cập nhật câu trả lời với một sự ghi nhận. Cảm ơn.
zero323

92

Từ các bình luận trang sách dạy nấu ăn MongoDB :

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

Điều này làm việc cho tôi. Trong ngữ cảnh đầy đủ, lệnh sau nhận được mọi bản ghi trong đó trường dtngày có ngày vào ngày 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
Tôi gặp lỗi "ISODate không xác định". Tôi không thể giải quyết vấn đề này.
Batuhan Akkaya

@BatuhanAkkaya Trong trăn với pymongo, datetime.datetimetương đương với ISODate.
jtbr

12

Thử cái này:

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

5

Tôi đang sử dụng robomongo với tư cách là khách hàng mongodb và những điều dưới đây làm việc cho tôi

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

Về phía ứng dụng tôi đang sử dụng trình điều khiển mongodb dựa trên nodejs (v1.4.3), ứng dụng sử dụng công cụ hẹn hò trong ui có ngày như YYYY-mm-dd, sau đó được thêm vào với thời gian mặc định như 00:00:00 và sau đó được đưa ra cho hàm new Date()tạo và sau đó được cung cấp cho đối tượng tiêu chí mongodb, tôi nghĩ trình điều khiển chuyển đổi ngày thành ngày ISO và truy vấn sau đó hoạt động và cung cấp đầu ra mong muốn, tuy nhiên, cùng một hàm new Date()tạo không hoạt động hoặc hiển thị cùng một đầu ra trên robo mongo, cho cùng tiêu chí, thật kỳ lạ, vì tôi đã sử dụng robomongo để kiểm tra chéo các đối tượng tiêu chí của mình.

Trong khi đó, closh mongoshell mặc định hoạt động tốt với cả hai ISODatenew Date()


1
Cảm ơn bạn vì tiền boa, Robomongo tốt hơn Mongo Compass
Alex

5

Trong chế độ nghiêm ngặt của json, bạn sẽ phải giữ trật tự:

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

Chỉ có điều làm việc để xác định truy vấn tìm kiếm của tôi trên mlab.com.


Lỗi khi chạy truy vấn. Lý do: (không hợp
lệ_operator

2

Trong trình bao MongoDB:

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

Trong mã nodeJS của tôi (sử dụng Mongoose)

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

Tôi đang truy vấn bộ sưu tập sự kiện cảm biến của mình để trả về các giá trị trong đó trường 'từ' lớn hơn ngày đã cho


4
Chào mừng bạn đến với Stack Overflow! Xin vui lòng chỉ gửi câu trả lời cho câu hỏi, và không thêm những thứ như "Đây là bài viết đầu tiên của tôi". Hãy nghĩ về Stack Overflow như Wikipedia, không phải bảng tin.
durron597

1

đây là tài liệu của tôi

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

bây giờ tôi muốn tìm mọi tài liệu ngày 27. vì vậy tôi đã sử dụng nó ....

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

result:1

Điều này làm việc cho tôi.


0

Điều này làm việc cho tôi trong khi tìm kiếm giá trị nhỏ hơn hoặc bằng so với bây giờ:

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

0

Gói nó với new Date():

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

0

Câu hỏi cũ, nhưng vẫn là google đầu tiên, vì vậy tôi đăng nó ở đây để tôi tìm thấy nó dễ dàng hơn ...

Sử dụng Mongo 4.2 và tổng hợp ():

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

Cái này cung cấp cho bạn biến nhóm theo ngày, đôi khi tốt hơn để xử lý như chính các thành phần.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.