mongodb date query don't work with ISODate? - mongodb

I can find an item with this search:
db.item.find({"startdate":{$gte: 1485521569000 }})
The date seems to correspond to
> new Date(1485521569000)
ISODate("2017-01-27T12:52:49Z")
But if I search
db.item.find({"startdate":{"$gte" : ISODate("2017-01-01T00:00:00Z")}})
I don't get any results. What am I doing wrong?
PS
the only way I found is
db.item.find({"startdate":{"$gte" : (new Date("2017-01-01")).getTime()}})
is that right or there is a better way?

Below one will work.
db.getCollection('test').find({
"key": {
"$gte": (ISODate("2017-01-01")).getTime()
}
})
Reason:
You have your data is in int64 or long
In the new Date query, you are converting date to time which return int. So get performs integer comparison.
In ISODate you are passing a date, it doesn't convert date to integer i.e milliseconds. So if you convert, both will work.
new Date() returns the current date as a Date object. The mongo shell wraps the Date object with the ISODate helper
var d = ISODate("2017-01-01")
print(d); //Sun Jan 01 2017 05:30:00 GMT+0530 (IST)
Hence, the comparison fails.

If i understand, you have timestamp in startdate field,
This is the option if helps you, Can do it with aggregate() function, using $toDate,
$toDate convert timestamp to ISO date
db.collection.aggregate([
{
$match: {
$expr: {
$gte: [
{
$toDate: "$startdate"
},
ISODate("2017-01-27T12:52:49.000Z")
]
}
}
}
])
Playground: https://mongoplayground.net/p/H7SFHsgOcCu

Related

I can not get dates after my current date

I want to obtain the records that the "FECHA_FIN" field is greater than or equal to today's date.
this is an example of my data:
but with this query:
db.getCollection('susp_programadas').find( {"FECHA_FIN":{ $gte: new Date("YYYY-mm-dd") }} )
I do not get results, what am I doing wrong? Thank you
You can convert the date to an ISO date and query that way. Since you stored the date as a string mongo has no idea how to query it against an ISO date without conversion.
If you stored your date in mongo as the default ISO date then you could have easily done this:
db.getCollection('susp_programadas').find({"FECHA_FIN":{$gte: new Date()}})
So this is how you can do it now:
db.getCollection('susp_programadas').aggregate([
{
$project: {
date: { $dateFromString: { dateString: '$FECHA_FIN' }}
}
},
{ $match: { date: { $gte: new Date() }}}
])
You can use the $dateFromString in an aggregate query with a $match to get the results you want. Note that $dateFromString is only available in MongoDB version 3.6 and up.
If there is no way to convert your data to ISODate or upgrade your DB you could also consider another solution which via $where:
db.getCollection('susp_programadas').find({
$where: function(){
return new Date(this.FECHA_FIN) > Date.now()
}
})
However that solution suffers from the fact that $where can not use indexes so have that in mind.

How to convert a date stored as string in MongoDB to ISODate?

I have a collection in which each document has a time field with value stored as similar to "21-Dec-2017".
I want to convert this to ISODate using projection.
My Query:
db.getCollection('orders').aggregate([{
$project:{time : {$add : new Date("$time")}}
}])
But this is returning me ISODate("1970-01-01T00:00:00.000Z") always.
you can try this,
db.getCollection('orders').aggregate([{
$project: {
time: {
$dateToString: {
format: "%d-%m-%G",
date: new Date("$time")
}
}
}
}
])
there is no any string function to get months name eg.Jan,Feb..Dec.
but you can refer https://docs.mongodb.com/manual/reference/operator/aggregation/dateToString/
to more information.
There is no problem in this ISODate("1970-01-01T00:00:00.000Z") format.
you should store date in ISO format but change format on client side according to you.
Basically you want to show date in dd/mm/yy format.
You can use http://momentjs.com/ to show date according to you.

Cannot use $dayOfMonth aggregate with expression

So, I need to extract the day-of-week for some objects to make some aggregations. But all my documents have is a timestamp, not a Date. So I'm trying to use $dayOfMonth (and others) with an expression, I can't figure out what it is not working.
Here is my query (along with a helper function to create my date from the timestamp):
db.Logging.aggregate([
{
$match: {
"timestamp": { $gte: dateToTimestamp("2017-04-10") }
}
},
{
$project: {
_id: 0,
timestamp: "$timestamp",
dia: { $dayOfMonth: myDate("$timestamp") }
}
}
])
function dateToTimestamp(str) {
let d = new Date( str );
return d.getTime() + d.getTimezoneOffset()*60*1000;
}
function myDate( ts) {
var d = new ISODate();
d.setTime( ts );
return d;
}
The problem seems to be in passing the value of $timestamp to the myDate function. If I use a literal (e.g. 1492430243) either as the value of ts inside the function or as the value of the parameter passed to myDate it works fine.
In other words: this $dayOfMonth: myDate("1492430243") works.
Although a solution has been shown to work here (Mongodb aggregation by day based on unix timestamp - a pretty ugly solution, if I may add), I want to know why my solution doesn't. As per mongodb docs, $dayOfMonth works with Date types, my function returns a date, so what is wrong?

find document in today's date range in mongodb

I have a collection, Plans. I want to find everything within the range of one month. Here is a sample of what the data could look like:
{
"_id": "someid",
"dateStart": ISODate("2015-03-01T00:00:00Z"),
"dateEnd": ISODate("2015-03-31T00:00:00Z"),
"items": [
"someotherid"
]
}
How can I find the Plan such that today's date is between dateStart and dateEnd?
To find a Plan such that today's date is between the dateStart and dateEnd fields, create a date object that holds the current date then use the $lt and $gt query operators on the date fields to query documents where today's date falls between the two fields:
currentDate = new Date();
Plans.find({
dateStart: { $lt: currentDate },
dateEnd: { $gt: currentDate }
});
date1 = new Date('3/1/15');
date2 = new Date('4/1/15');
Plans.find({
startDate: {$gte: date1},
endDate: {$lt: date2}
});
New Date objects initialize to 00:00:000 so you can use that to your advantage here. Also note that "less than 4/1" is equivalent to "less than or equal to midnight on 3/31" - but the former is much easier to write.
Also note that moment is a super handy utility for doing manipulations like this. For example: moment().endOf('month').toDate()
To add the package just do:
$ meteor add momentjs:moment

Convert BSON ISODate to NumberLong in MongoDB

I have a collection in MongoDB that has created fields with values currently stored as a BSON ISODate object. I want to convert all of those to NumberLong objects containing a timestamp.
First I tried this (in Mongo shell):
db.collection.find( { "created" : { "$type" : 9 } } ).forEach( function (x) {
x.created = new NumberLong(x.created);
db.collection.save(x);
});
JavaScript execution failed: Error: could not convert "Tue Mar 18 2014 18:11:21 GMT-0400 (EDT)" to NumberLong
Apparently a date string cannot be cast as a long...fair enough. Then I tried this, thinking I could make use of the Javascript Date object's UTC method:
db.collection.find( { "created" : { "$type" : 9 } } ).forEach( function (x) {
x.created = new Date(x.created).UTC();
db.collection.save(x);
});
JavaScript execution failed: TypeError: Object Tue Mar 18 2014 18:11:21 GMT-0400 (EDT) has no method 'UTC'
I've tried several other variations, but nothing has worked yet. Any help would be greatly appreciated!
To access the underlying numeric value of the Date, you can call getTime() on it:
x.created = new NumberLong(x.created.getTime());
The ISODate object has a "valueOf" method that will return an epoch time. Here is an example generating this via mongo shell:
replset:PRIMARY> var date = ISODate()
replset:PRIMARY> date
ISODate("2014-06-25T16:31:46.994Z")
replset:PRIMARY> date.valueOf()
1403713906994
replset:PRIMARY>