简体   繁体   中英

NodeJS MongoDB: Querying ISO Date

I have a collection of ISO dates stored in MongoDB as strings, like so:

{ "date": "2014-12-12T03:33:33.333Z" },
{ "date": "2014-12-13T03:33:33.333Z" }

In the console, I can query these perfectly using

{ "date": ISODate("2014-12-12T03:44:00.000Z") }

However, I'm using the NodeJS driver, and I cannot use ISODate . I have found several questions pertaining to this problem on here, but none of the proposed solutions seem to work. For instance:

// These does not find any matches
db.find({ "date": new Date("2014-12-12T03:44:00.000Z") })
db.find({ "date": { '$eq': '2014-12-12T03:44:00.000Z' } })
db.find({ "date": { '$eq': new Date('2014-12-12T03:44:00.000Z') } })

//This throws an error stating $date is not an operator
db.find({ "date": { '$date': '2014-12-12T03:44:00.000Z' } })

Why are these queries failing?

Edit: Here's another sample, straight from the database:

{
    "_id": "5a7e88f34b5916723589183f",
    "date": "2014-12-12T03:42:00.000Z",
    "granularity": 180
}

EDIT 2: This query produces the following error MongoError: $dateFromString requires that 'dateString' be a string, found: date with value 2014-12-12T03:44:00.000Z

async loadCandle(date, granularity) {        
        date = date + ''; //Aded to ensure date is a string, but still get the error.
        var candle = await this.data.collection('dates').findOne( 
            { $expr : 
                {$eq : 
                    [
                        {$dateFromString : {dateString : "$date"}}, 
                        new Date("2014-12-12T03:33:33.333Z") //Normally would pass in the `date` variable here
                    ]
                } });

because $date is not an operator

you need to use $dateFromString to convert string date to ISODate for comparison

db.datez.find(
    {$expr : 
        {$eq : 
            [
                {$dateFromString : {dateString : "$date"}}, 
                new Date("2014-12-12T03:33:33.333Z")
            ]
        }
    }
)

using aggregation

db.datez.aggregate([
    {$match : 
        {$expr : 
            {$eq : 
                [
                    {$dateFromString : {dateString : "$date"}}, 
                    new Date("2014-12-12T03:33:33.333Z")
                ]
            }
        }
    }
])

collection

> db.datez.find()
{ "_id" : ObjectId("5a7e795e80aae386f73cf0fe"), "date" : "2014-12-12T03:33:33.333Z" }
{ "_id" : ObjectId("5a7e795e80aae386f73cf0ff"), "date" : "2014-12-13T03:33:33.333Z" }
> 

result

> db.datez.find({$expr : {$eq : [{$dateFromString : {dateString : "$date"}}, new Date("2014-12-12T03:33:33.333Z")]}})
{ "_id" : ObjectId("5a7e795e80aae386f73cf0fe"), "date" : "2014-12-12T03:33:33.333Z" }

You can use $dateToString operator which generate the string date of any specified format, which can be compared later.

For string comparison of date, input format should be YYYY-MM-DD, any other format would get fail for ranges date queries

Let me explain through example:

Here is my collection in mongoDb :

{
    "_id" : ObjectId("5f2d0a0c632ec022e08c3191"),
    "date" : ISODate("2020-07-12T00:00:00Z")
}
{
    "_id" : ObjectId("5f2d0a12632ec022e08c3192"),
    "date" : ISODate("2020-07-13T00:00:00Z")
}

Now the query to be fired from Node for comparison of such stored ISODates is as follow

db.collection.aggregate(
    [
        {
            $addFields: {
                formattedDate: { // An extra field "formattedDate" is added in each document which can be compared later through pipeline using $match
                    $dateToString: {
                        format: "%Y-%m-%d",
                        date: "$date" // in "$date" date is variable from db
                    }
                }
            }
        },
        {
            $match: {
                formattedDate: {
                    $eq: "2020-07-12" // here you can provide your input date yyyy-mm-dd
                }
            }
        }
    ]
)

So for above query you will get output as

{
    "_id" : ObjectId("5f2d0a0c632ec022e08c3191"),
    "date" : ISODate("2020-07-12T00:00:00Z"),
    "formattedDate" : "2020-07-12"
}

Hope this will help you or somebody else!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM