Date range queries mongodb - mongodb

I've two collections one is random and other one is 'msg'
In message I've a document like
{ "message": "sssss", postedAt: Fri Jul 17 2015 09:03:43 GMT+0530 (IST) }
For random collection, there is a script which generates random number every minute
like
{ "randomStr": "sss", postedAt: Fri Jul 17 2015 09:03:43 GMT+0530 (IST) }
{ "randomStr": "xxx", postedAt: Fri Jul 17 2015 09:04:43 GMT+0530 (IST) }
{ "randomStr": "yyy", postedAt: Fri Jul 17 2015 09:05:43 GMT+0530 (IST) }
Notice the change in timings, for every mintute there is a new record.
Now, my issue is
when I query for message collection, I'll get one record.
Lets's say this
{ "message": "sssss", postedAt: Fri Jul 17 2015 09:03:13 GMT+0530 (IST) }
now I want to get the record from random collection which posts at exact minute
this message is posted at 09:03, I want to get the record from random collection which postedat exactly same time 09:03.
How to do that? Any help appreciated. Thx.
Note: I'm doing this in meteor
Edit
Added image for first comment

So the point here is 'actually use a range' and also be aware of the Date value you get in return. So as a basic example in principle.
The time right now as I execute this is:
var date = new Date()
ISODate("2015-07-17T04:02:04.471Z")
So if you presume then that your actual timestamp in the document is "not exactly to the minute" (like above) nor is it likely the "random record" is so then the first thing to do is "round" it to the minute:
date = new Date(date.valueOf() - date.valueOf() % ( 1000 * 60 ))
ISODate("2015-07-17T04:02:00Z")
And of course the "end date" is just one minute after that:
var endDate = new Date(date.valueOf() + ( 1000 * 60 ))
ISODate("2015-07-17T04:03:00Z")
Then when you query "rqndom" you just get the "range", with $gte and $lt operators:
db.random.find({ "postedAt": { "$gte": date, "$lt": endDate } })
Which just retrieves your single "write once a minute" item from "random" at any possible value within that minute.
So basically:
Round your input retrieved date to the minute
Search on the "range" betweeen that value and the next minute

Related

How can compare Date on mongo without time?

This is a sample data
[{ date: '2020-05-21T14:02:00.0123 }, { date: '2020-05-22T14:02:00.0123 }, { date: '2020-05-23T14:02:00.0123 }]
I want to filter records of 22-May or earlier, here is my expected:
[{ date: '2020-05-21T14:02:00.0123 }, { date: '2020-05-22T14:02:00.0123 }]
I tried with this query:
{ date: { $lte: new Date('2020-05-22') }}
But it returns only data earlier 22-May. I think problem is { date: { $lte: new Date('2020-05-22') }} will data.date lte 2020-05-22T00:00:00.000
How I can exclude time ?
You need to match type of input with type of date field in document, either both should be Date's or strings. I would highly suggest maintain dates as dates in DB. Also you need to know that dates in MongoDB are of format ISODate() and holds UTC date.
If your DB date field is of type date :
I want to filter records of 22-May or earlier
As you wanted to get documents <= 22-May, then sending new Date('2020-05-22') doesn't work. Cause :
when you do new Date('2020-05-22'), it will give you Fri May 22 2020 00:00:00 GMT only if you belong to UTC, for example if you're in New York America which is 4 hours behind UTC then it would result in Thu May 21 2020 20:00:00 GMT-0400 (Eastern Daylight Time) which represents EDT, basically it's your system/app server time i.e; local date time.
So if your region is behind UTC then you'll get a back date Thu May 21 2020 otherwise if it's ahead of UTC then there is no issue you'll see Fri May 22 2020.
Ok, now that we've fixed date issues, but we need to look into hours now :
Since you want docs <= 22-May then Fri May 22 2020 00:00:00 GMT doesn't work you need to have either <= Fri May 22 2020 23:59:59 GMT or Sat May 23 2020 00:00:00 GMT. In order to get that :
let date = new Date('2020-05-22')
date.setDate(date.getUTCDate()); // Setting utc date, Only useful if you're region is behind UTC
date = new Date(date.setHours(23,59,59,999)) // This overrides hours generated with 23:59:59 - which is what exactly needed here.
/** Now do your query */
{ date: { $lte: date }}
If your DB date field is of type string :
Then you don't need to convert string to date, instead you can send input date in string format :
let date = new Date('2020-05-22').toISOString() // 2020-05-22T00:00:00.000Z
/** Above would get you an ISO string no matter which region you're in, 
* now since we need `2020-05-22T23:59:59.000Z` which is not easy on ISO string
* We would just do +1 on date like `new Date('2020-05-23').toISOString()` - // 2020-05-23T00:00:00.000Z */
let date = new Date('2020-05-23').toISOString(); // like this
date = date.slice(0, -1) // removing `Z` from date string as your `date` field doesn't have this.
// Now your query is just `$lt`
{ date: { $lt: date }}
Test : mongoplayground

How do I use the $gte and $lte for dates in mongodb?

I have data in a collection. Each stored data was stored along with times indicating the times each data was inserted into the collection.
I have an issue formulating a query that shows data stored between the beginning of a specific month and the end of a specific month.
Kindly help me with what is wrong with my query.
Find below the content of my collection.
Meteor.users.find({}).fetch();
(2) [{…}, {…}]
0: {_id: "ZwT3hcmabytf82wyK", createdAt: Mon Dec 03 2018 11:16:53 GMT+0300 (East Africa Time)}
1: {_id: "SEXZoHzt3ryKC2a4r", createdAt: Mon Dec 03 2018 11:16:34 GMT+0300 (East Africa Time)}
length: 2
Kindly note that the createdAt suggests the inserted data time, being: Monday 3rd December 2018 e.t.c.
And now note my query below. That beginningOfMonth variable and the endOfMonth variables are both set to the November month (beginningOfMonth.setMonth(10, 1) & endOfMonth.setMonth(10, 28)), and yet the results of the query is wrong:
var beginningOfMonth = new Date();
var endOfMonth = new Date();
beginningOfMonth.setMonth(10, 1);
endOfMonth.setMonth(10, 28);
Meteor.users.find({}, { createdAt: { $gte: beginningOfMonth, $lt: endOfMonth} }).fetch();
[{…}]
0:{_id: "SEXZoHzt3ryKC2a4r",
createdAt: Mon Dec 03 2018 11:16:34 GMT+0300 (East Africa Time),
length: 1__proto__: Array(0)
Note that that the results of the query are wrong. The query seems to ignore the dates section createdAt: { $gte: beginningOfMonth, $lt: endOfMonth}.
Kindly help and show me what I am doing wrong.
Thanks in advance
show me what I am doing wrong.
You're not properly using meteor api. Pass your criteria as the first parameter.
Meteor.users.find({ createdAt: { $gte: beginningOfMonth, $lt: endOfMonth} }).fetch();

find results not matching date in selector

A Meteor client Template returns mongodb cursor. The collection has 3 documents which contain date field. I expected the find to return 3 documents, but it only gave one the date of which is Mon Aug 08 2016 00:00:00 GMT+1000 (AEST).
Why is that and how can I get the 3 documents? Thanks
"date" : ISODate("2016-08-08T14:00:00Z"),
"date" : ISODate("2016-08-08T14:00:00Z"),
"date" : ISODate("2016-08-07T14:00:00Z"),
console.log(start); //=> Sun Aug 07 2016 00:00:00 GMT+1000 (AEST)
console.log(end); //=> Mon Aug 08 2016 00:00:00 GMT+1000 (AEST)
console.log(myCol.find({date: {$gte: start, $lte: end}}).fetch()); // expected 3 not just 1
the code below shows how the date was before inserting in the collection.
const date = cheerioObj(this).next().html().trim();
const dArr = date.split('/');
const dObj = new Date(parseInt(dArr[2]), parseInt(dArr[1]) - 1, parseInt(dArr[0]));
EDIT: Sorry, it's late.
It may be to do with your .fetch() method. Try iterating the cursor instead:
var myArray = db.users.find({...}).toArray();
Then access each in a for loop.

Between query in mongoDb by using start date and end Date (IST)

I am able to get data by using below query for integer from my table of mongoDb by using umongo UI Interface.
{ sequence: { $gt: 4035 } }
{sequence:{$gte:4035,$lte:4035}}
Both above queries are working fine
but in the same table or collection I have one column schedules inside the schedules I have startDate endDate column
by using this column I want to execute "between clause" on the basis of start date and end date like below but no records are showing .
{'schedules.start': {'$gte': "1-1-2014",'$lt': "14-1-2016"}}
or
{'schedules.start': {$gte: '1-1-2014',$lt: '14-1-2016'}}
or
{'schedules.start': {$gte: 1-1-2014,$lt: 14-1-2016}}
or
{ 'schedules': {'$gt': 'date':'Wed Jan 01 05:30:00 IST 2014', '$lt': 'date' :'Wed Dec 31 05:30:00 IST 2014'}}
so I need between query on the basis of starDate and endDate.
My table structure:
site--> schedules-->star(date):Wed Jan 01 05:30:00 IST 2014
end(date) :Wed Dec 31 05:30:00 IST 2014
Here I am attaching screen shot of my table.
Thank you in advance
Can you wrap it with an $and clause?
{
$and: [
{'schedules.startDate': {$gte: 1-1-2014}},
{'schedules.endDate': {$lt: 14-1-2016}}
]
}
Obviously you'll need to adjust naming conventions to your model.

IndexedDB with range queries

I would like to find which date ranges overlaps another date range in IndexedDB.
Something like the following query:
SELECT * FROM events
WHERE (periodStart >= start AND periodStart < end)
OR (start >= periodStart AND start <= periodEnd)
Events looks like the following object:
[{
title: 'foo',
start: 'Tue Oct 29 2013 10:19:52 GMT-0400 (EDT)',
end: 'Tue Oct 29 2013 13:19:52 GMT-0400 (EDT)'
},
{
title: 'bar',
start: 'Tue Oct 30 2013 00:00:00 GMT-0400 (EDT)',
end: 'Tue Oct 31 2013 00:00:00 GMT-0400 (EDT)'
}]
To my knowledge, no ability to do unions in indexeddb (the OR).
So, as that kinda sucks, here is a half thought out solution that maybe puts you on the course: something like find the min of the set, and the max of the set, and then a query descending and a query ascending but just get the first record from each cursor, and then, something.