Query a Timestamp in MongoDB - 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.

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();
}

Getting Mongo results from one month ago

I have around 30-40 records like the example before in my database and I'm looking to get the notifications that are less than 1 month old (from today's date). Is there a way in Mongo to get these results without having to pass in a today's date via JavaScript? Or if I do have to pass it in via JavaScript, how would I process this against my created date?
{
"_id" : ObjectId("48445b4dc72153e9ad7f3bfb"),
"notificationID" : "78723asd5-vnbb-xv31-afe0-fa9asf164e4",
"notification" : "Notification #1",
"created" : ISODate("2016-11-21T20:33:53.695Z")
}
Any help is appreciated, thanks.
MongoDB has its own Javascript interpreter so, unless your MongoDB server has a different date than your system, it knows the current date so you easily use simple Javascript to compute the value you're looking for using a regular Date object and use it in your query.
var d = new Date();
d.setMonth(d.getMonth() - 1); //1 month ago
db.data.find({created:{$gte:d}}); //change "data" for your collection's name
If you need a different date than your database's, I'm afraid you'll have to somehow pass it as a parameter.
const now = new Date()
const temp = new Date(now).setMonth(now.getMonth() - 6);
const priorSix = new Date(temp)
Table.find({"date" : {$gte: priorSix, $lt: new Date()}}, (err, tables) => {
if(err) throw new Error(err)
res.status(200).json(tables)
}).populate('foodList.item')
This code worked for me. It retrieves documents of the last 6 month :)

mongo find query on joda datetime

i am trying to use find query in mongodb to determine the records on that specific date , the query is working fine when i pass it the normal date object and if i find according to dateCreated field, but for joda date field, i don't know how should i form a joda date
right now i am using this query for normal records
var from = new Date('2015-05-18T00:00:00.000Z');
var to = new Date('2016-05-19T00:00:00.000Z');
db.delivery.find( {"dateCreated" : { $gte:from,$lt:to } } );
now i also have a field called deliveryDate which is of type joda date and stored like this
"deliveryDate" : {
"jodaType" : "org.joda.time.DateTime",
"interval_start" : ISODate("2015-03-28T18:30:00Z"),
"interval_end" : ISODate("2015-03-28T18:30:00Z"),
"jodaField_zone" : "UTC",
"time" : NumberLong("1427567400000"),
"jodaField_dayOfMonth" : 28,
"jodaField_hourOfDay" : 18,
"jodaField_minuteOfHour" : 30,
"jodaField_millisOfSecond" : 0,
"jodaField_monthOfYear" : 3,
"jodaField_year" : 2015
},
i googled a lot but with no success, i have no idea how can i query for joda date ,please help!
Your joda date is serialised into a nested JSON object. You should be able to query on it using interterval_start
db.delivery.find( {"deliveryDate.interval_start" : { $gte:from,$lt:to } } );

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

Forming queries with comparison query operators and ISODate from groovy to get data from mongodb

Here is my sample JSON from eventSchedule collection in mongodb:
/* 0 */
{
"_id" : ObjectId("51cd841b8b757a8c4c3b0af9"),
"type" : "evo",
"eventInfo" : {
"title" : "My title",
"field1" : "MyField1",
"schedule" : {
"fromDate" : ISODate("2013-07-19T04:00:00Z"),
"toDate" : ISODate("2013-07-25T20:00:00Z")
}
},
"locationName" : "Loc1"
}
I want to query this collection and get all eventSchedules with schedule field "fromDate" after the present date.
In mongoVUE, following query works:
db.eventSchedule.find({ "eventInfo.schedule.fromDate" : { "$gte" : ISODate("2012-04-29T00:00:00Z") } }).limit(50);
I am trying to do it from one of my grails controller as:
def curDate= new Date()
def sdf= new SimpleDateFormat("yyyy-mm-dd")
def curFormattedDate= sdf.format(curDate)
def queryVal= "{\$gte : ISODate(\""+curFormattedDate+"T00:00:00.000Z\")}"
query.put("eventInfo.schedule.fromDate:", queryVal.trim())
DBObject a = db.eventSchedule.findOne(query)
println a
Above code returns the value of a to be null. Pls note that if i remove the enclosing braces from queryVal, then also it does not work.So can anyone help me form the appropriate query in groovy?
There are few areas where you need to rectify creating the query:
mm in date format represents minutes and not Month. Use MM instead.
Don't you need to escape " for $gte if you really want to stick to the mongoVUE version?
def queryVal= "{\"\$gte\" : ISODate(\""+curFormattedDate+"T00:00:00.000Z\")}"
BTW, a groovier way to format date is
def currentFormattedDate = new Date().format('yyyy-MM-dd')