Mongodb get information by date (timestamp stored in db) - mongodb

I need to get all information stored in my (mongo)DB in a collection filtered by a date.
The problem is that I store a timestamp in my BD, and I need to get all information for a day.
Example, if I chose the 2014-01-08, I have to get all the treatment done during this day
Can you help me with the mongo request ?
Thanks for advance

Query by using a date range with a "range based query", which is a simple treatment of the $gte and $lt operators:
Assuming you actually mean "YYYY-MM-DD" as in "year" "month" "day":
db.collection.find({
"dateField": {
"$gte": new Date("2014-08-01"),
"$lt": new Date("2014-08-02")
});
So that basically selects all items that fall within that date range being only occurring on "2014-08-01" only. So the range is all values that fall within that range.
If your timestamp is actually a number ( milliseconds since epoch ) then you just extract those values from date objects you create and send those in the query:
db.collection.find({
"dateField": {
"$gte": new Date("2014-08-01").valueOf(),
"$lt": new Date("2014-08-02").valueOf()
});
The same principle applies for just about any language as the supported DateTime object will have a method to do so.
If you are doing this then you might re-consider your approach. MongoDB uses a BSON Date type, which aside from the "type" identifier, actually stores the timestamp number internally. So there is basically no overhead to BSON dates, and they automatically inflate to DateTime objects with all drivers, as well as being supported by other internal operators.

Related

How to embed the date-to-timestamp conversion in a mongodb query?

Suppose I have documents in a mongo collections with a timestamp field. I want to query the documents based on the timestamp value (greater than, less than). In order to do that, instead of calculating each time the timestamp for my current date, I would like to embed the conversion from the date to timestamp in the query. I tried something like this (suppose "ts" is my timestamp field):
db.my_collection.find({"ts": {$lt: {$toLong : new Date("2020-12-09")}}})
instead of doing:
db.my_collection.find({"ts": {$lt: 1578524400}})
but it seems to return an empty result.
Is there a result to perform the date-to-timestamp conversion inside the query?
You can use $toLong but it's an aggregation pipeline operator, you need an aggregation pipeline not a plain find.

Query mongodb for a specific date range

I've googled and googled this, and for the life of me I can't make it work...which I know I am just missing something totally simple, so I'm hoping someone here can save my sanity.
I have am trying to lookup a range of documents from a mongodb collection (using mongoose) based on a date range.
I have this code:
var startDate = new Date(req.query.startDate);
var stopDate = new Date(req.query.stopDate);
studentProgression.find({ $and: [ {'ACT_START': {$gte: startDate, $lte: stopDate} } ]})
But it doesn't return any documents.
The date in the MongoDb collection is stored as a string, and looks like this (for example):
ACT_START: "25-MAY-20"
a
I know I'm probaby tripping somewhere with the fact it's a string and not a date object in mongo, as I haven't had this issue before. I'd rather not go through the collection and change all the string dates to actual date objects.
Is there anyway to do this lookup the way I've laid it out?
Unfortunately, you have to change the format of your ACT_START field and cast it to a Date.
By doing $gte and/or $lte on a string field, mongo will compare the two strings based on their alphabetical order.

why does $eq comparison is not working on mongodb with dates

I have the following query on mongo
db.getCollection('someCollection').find({"status":"failed","start_date": {$gt: new Date("2019/03/01")}})
that will retrieve all the records that have a failed status and the start_date is equal or greater than "2019/03/01".
But when i try to only retrieve records specifically for "2019/03/01":
db.getCollection('someCollection').find({"status":"failed","start_date": {$eq: new Date("2019/03/01")}})
It doesn't retrieve anything.
$lt and $gt queries work is just $eq that doesn't work. is that the correct way to use the $eq?
thank you
When you use new Date("2019/03/01") the actual date being searched is 2019/03/01 00:00:00.00. That is, the Date is exactly midnight 2019/03/01 (down to the millisecond). Unless your record also has the exact same date recorded, it will not match. That's why you need to use {$gt: new Date("2019/03/01"), $lt: new Date("2019/03/02")}. Just think of it as that 1 "day" is actually a range of 24 hours. Which is why you need to specify it as a range, and not as a simple $eq comparison.
The reason why your first query works is because when you search for $gt 2019/03/01 you're really searching for $gt 2019/03/01 00:00:00.00. And so, of course every record started on 2019/03/01 will match.
One thing to take note of: technically, if you have a document made exactly at midnight i.e. with a timestamp of 2019/03/01 00:00:00.00, it won't match. So you really should use {$gte: new Date ('2019/03/01')} (note the extra 'e'). $gte is greater than or equal. This may sound trivial but is actually important, because if you don't use actual timestamps and record just the date when you create the record (i.e. you insert with {start_date: new Date('2019/03/01')}, all those timestamps will actually have 00:00:00.00 as their time component, and they won't match with a $gt comparison, only a $gte comparison. You probably use new Date() when creating the record, so you're getting the full timestamp, which is why it hasn't bitten you yet. But to be semantically correct, you should use $gte in your first query. Does that make sense?

ISO8601 Date Strings in MongoDB (Indexing and Querying)

I've got a collection of documents in MongoDB that all have a "date" field, which is an ISO8601 formatted date string (i.e. created by the moment.js format() method).
I'd like to be able to efficiently run queries against this collection that expresses the sentiment "documents that have a date that is after A and before B" (i.e. documents within a range of dates).
Should I be storing my dates as something other than ISO-8601 strings? Contingent upon that answer, what would the MongoDB query operation look like for my aforementioned requirement? I'm envisioning something like:
{$and: [
{date: {$gt: "2017-05-02T03:15:22-04:00"}},
{date: {$lt: "2017-06-02T03:15:22-04:00"}},
]}
Does that "just work"? I need some convincing.
You definitely want to use the built-in date data type with an index on your date field and not strings. String comparison is going to be slow as hell compared to comparing dates which are just 64bit integers.
As far as querying is concerned, check out the answer here:
return query based on date

Elastic Search Date Range Filter Not Working

Context
I have an index with a field called "date" which contains dates. I need an elasticsearch query that returns records where date is greater than a specific date value.
Issue
Running the following query with range filter returns does not work. Records with earlier dates are returned in the result set.
{
"size": 1000,
"query": {
"filtered": {
"filter": {
"range": {
"date": {
"gt": "2014-02-23T00:00:00"
}
}
}
}
}
}
Questions
What is the correct query to pull data where date is greater than a
specific value?
If my query is syntactically correct, is there
something else I can go check (e.g. datatype of field is actually
date)?
How should I go about root causing this?
etc.
Solution
In lieu of implementing mapping, I came up with a partial solution. I used Chrome to analyze some of the Kibana traffic. I noticed Kibana is passing date filters as int values. So, I converted the dates to ints using Unix timestamp conversion and things are working now.
(Reference http://www.epochconverter.com/)
What about mapping?
I looked at the mappings earlier. On my index they don't exist. I seem to recall reading that mappings will be inferred for known types that have strong consistency.
My date data is consistent:
- no nulls
- dates are getting flipped from SQL, to C#, to Elastic
I guess I could implement a mapping, but I'm going with the Epoch conversion for now until I have a true need to map this for some other compelling reason.
Your query is syntactically correct.
Use get mapping API to see the document mapping:
curl -XGET 'http://localhost:9200/twitter/_mapping/tweet'
It's hard to say where goes wrong. Probably the mapping of date field is not date type actually.