Reset ISODate with time stamp to midnight in MongoDB - mongodb

I have a use case to query as below.
The time stamp passed would like 2018-09-01T12:23:32 like ISODate. Mongo version 3.5. How to query in such cases?
mongo_client.find(
"date":{
'$gte': {<midnight on the date of date key},
'$lt': {<searchkey with time stamp>}
})

you can create start and end dates, use it for querying
> var end = new Date("2018-01-30T04:05:23.974Z")
ISODate("2018-01-30T04:05:23.974Z")
> var start = new Date("2018-01-30")
ISODate("2018-01-30T00:00:00Z")
> db.col.find({date : {$gte : start}, date : {$lt : end}})

Related

Why spring data mongo not returning the field having time?

I have a document in my collection like
{
"_id" : ObjectId("5e3aaa7cdadc161d9c3e8014"),
"carrierType" : "AIR",
"carrierCode" : "TK",
"flightNo" : "2134",
"depLocationCode" : "DEL",
"arrLocationCode" : "LHR",
"depCountryCode" : "DELHI",
"arrCountryCode" : "LONDON",
"scheduledDepDateTime" : ISODate("2020-02-05T00:30:00Z")
}
{
"_id" : ObjectId("5e3aaacddadc161d9c3e8015"),
"carrierType" : "AIR",
"carrierCode" : "TK",
"flightNo" : "2021",
"depLocationCode" : "DEL",
"arrLocationCode" : "LHR",
"depCountryCode" : "DELHI",
"arrCountryCode" : "LONDON",
"scheduledDepDateTime" : ISODate("2020-02-05T00:00:00Z")
}
I am putting criteria like
Criteria criteria = new Criteria();
criteria = criteria.and("carrierCode").is("TK");
String from = "2020-02-05";
String to = "2020-02-05";
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date toDate = dateFormat.parse(to);
Date fromDate = dateFormat.parse(from);
criteria = criteria.and("scheduledDepDateTime").gte(fromDate).lte(toDate);
But i am getting document only the field which have time 00 not both the document. I have two documents with that date but in response getting only one. I have tried so many things but not succeed. I want to compare only the date and ignore the time. Please help.
The from and to dates must be the lowest time and the highest time for that date, respectively; this will cover all the hours of the day.
For using the same field ("scheduledDepDateTime") with the $and operator you must use the Criteria's andOperator not the and (see AND Queries With Multiple Expressions Specifying the Same Field).
The updated code:
Criteria criteria = new Criteria();
criteria = criteria.and("carrierCode").is("TK");
String from = "2020-02-05 00:00:00";
String to = "2020-02-05 23:59:59";
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd H:m:s");
Date toDate = dateFormat.parse(to);
Date fromDate = dateFormat.parse(from);
criteria = criteria.andOperator(where("scheduledDepDateTime").gte(fromDate), where("scheduledDepDateTime").lte(toDate)));
// Query qry = new Query(criteria);
// List<SomeClassName> result = mongoTemplate.find(qry, SomeClassName.class, "collection_name");
The ISODate in mongod is stored as an epoch timestamp with millisecond resolution.
dateFormat.parse is likely returning ISODate("2020-02-05T00:00:00.000Z"), which would be stored in the db as 1580860800000.
This effectively means your query is {scheduledDepDateTime:{$gte: 1580860800000, $lte: 1580860800000}}, so the only possible value that could satisfy the filter is ISODate("2020-02-05T00:00:00.000Z").
To get all documents with that date, you might try making your toDate be the following day, and use $lt instead of $lte.
As suggested by #prasad todate must be the lowest time and the highest time for that date I have to set time in todate field to 23:23:59 like this and it works.
public static Date convertToDate(final Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
return cal.getTime();
}

MongoDB : Time comparison

I have a field startTime in MongoDB collection that stores time in the following form:
2015-07-22 08:19:04.652Z
I would like to find all documents that has the startTime greater than or equal to yesterday's time(from exactly one day before). I tried using the $currentDate in the find query, but I was not able to make it work.
EDITED:
Sample Document:
{
"_id" : ObjectId("55af5241e4b0ec7c53360333"),
"startTime" : ISODate("2015-08-22T08:19:04.652Z"),
"sampleId" : "SS10"
}
EDITED 2: No aggregation framework allowed.
Compute the previous date first the pass it in find query.
In javascript:
var date = new Date();
date.setDate(date.getDate() - 1);
db.col.find({'startTime':{'$gte':date}})

Query a Timestamp in MongoDB

MongoDB document sample is given below:
{
"_id" : ObjectId("5f2df113bdde22f1043g45gg"),
"cd" : 1395376406,
"dob" : 552026006,
"e" : "test#gmail.com",
"g" : "M"
}
I need query to get birthday list for today using dob(date of birth) field(timestamp).
Thanks in advance!
I am not sure how elegant my solution is, but it should work
var start = new Date();
start.setHours(0,0,0,0);
var end = new Date();
end.setHours(23,59,59,999);
db.collection.find({dob:{$gt:start.getTime(), $lt:end.getTime()}})
Since MongoDb doesn't have any inbuilt functions/operations to support parsing raw timestamps and extracting information from them, you need to do the operation by passing a custom java script function to the server and get it executed there. This function would be executed for each record though.
db.collection.find({$where:function(){
var recDate = new Date(this.dob);
var recDay = recDate.getDate();
var recMonth = recDate.getMonth();
var today = new Date();
var todayDate = today.getDate();
var todayMonth = today.getMonth();
return (recDay == todayDate && recMonth == todayMonth);
}});
The function simply checks if any record's day and month match today's day and month.
Although this works for timestamps, you should take advantage of MongoDBs ISODate data type whenever you store date information. This enables us to use various operators and functions on these fields. Moreover they would be faster. If your document had the below structure:
{
"_id" : "1",
"cd" : 1395376406,
"dob" : ISODate("2014-11-19T08:00:00Z"),
"e" : "test#gmail.com",
"g" : "M"
}
Where, the dob field is of ISODate type. You could easily do a aggregate operation to fetch the results.
var todayDate = ISODate().getDate();
var todayMonth = ISODate().getMonth();
db.collection.aggregate([
{$project:{"day":{$dayOfMonth:"$dob"},
"month":{$month:"$dob"},
"_id":1,"cd":1,"dob":1,"e":1,"g":1}},
{$match:{"day":todayDate,"month":todayMonth}},
{$project:{"cd":1,"dob":1,"e":1,"g":1,"_id":1}}
])
The above operation utilizes the functions and operations that are allowed on a ISODate field. Querying becomes a lot easier and better.

Mongo DB: Query for documents currently "live" based on start and end date

Documents in my collection include this structure:
"time" : {
"start" : ISODate("2013-06-10T20:31:48.694Z"),
"end" : ISODate("2013-12-11T20:31:48.694Z")
}
Based off the current Time in which the query was made, I need Mongo to return which documents are currently "live" (in that the current time falls between the start and end time of each document).
The only mongo query I can find in this area queries for documents created between two Dates:
items.find({
created_at: {
$gte:"Mon May 30 18:47:00 +0000 2015",
$lt: "Sun May 30 20:40:36 +0000 2010"
}
})
What does this "live" query look like?
Like this:
var currentTime = new Date();
items.find({
'time.start': {$lt: currentTime},
'time.end': {$gt: currentTime}
});
Which will find the docs where the current time is between the start and end times in the doc.

Is there a way to display timestamp in unix format to ISODate?

We stored a date using unix timestamp in MongoDB, how do I get the date when I do the query? Is there a way to display timestamp in ISODate format?
Background
A unixtime value represents seconds since the epoch (Jan 1, 1970).
A JavaScript Date() represents milliseconds since the epoch.
In MongoDB, ISODate() is a convenience wrapper for Date() that allows you to create dates from ISO strings in the mongo shell. If you use new Date() in the shell, it will return an ISODate().
Conversion
To convert between a unixtime and an ISODate() you can multiply your unix timestamps by 1000 and pass this value to the new Date() constructor.
A simple example in the mongo shell:
> db.mydata.insert({
unixtime: 1362143511
})
> var doc = db.mydata.findOne();
// convert unixtime seconds to milliseconds and create JS date
> var date = new Date(doc.unixtime * 1000);
> date
ISODate("2013-03-01T13:11:51Z")
Mongodb 4.0 has introduced $toDate aggregation, so you can try with it
db.collection.aggregate([
{ "$project": {
"toDate": {
"$toDate": "$unixTimestamp"
}
}}
])
Try it here
In the Mongo console you can create a JavaScript Date object from a timestamp before the document is printed to the screen:
> db.stuff.find().forEach(function (doc) {
doc["timestamp_field"] = new Date(doc["timestamp_field"])
printjson(doc)
})
Be careful with that code, unlike a regular find() it will not page the results but print every matching document without pausing.