How to do a TIMESTAMP comparison in mongo DB? - mongodb

I have the following field in all my documents. And the Timestamp below will always be in string and I have no control to change it into any other type.
{ "TIMESTAMP": "2017-09-07T16:43:08.707-04:00" }
Since it is -04:00 the timestamp is in EST. but it can be in any timezone like -05:00 or -6:00 or whatever
The goal is to get all the documents that match the following criteria
currentTime > TIMSETAMP + 4 hours
where currentTime is in UTC and it is something I generate when I query.
I tried something like the following and I am not sure if there is anything wrong with this approach.
(new Date()- ISODate("2017-09-07T16:43:08.707-04:00"))/(60*60*1000) > 4

Related

timestamp in milliseconds and date range - elasticsearch query string

I have a timstamp in milliseconds, like 1645825932144
I'd like to make a date range query with elastic search query string for being able to get all records whom timestamp is in the last 24h:
timestamp:[now-24h TO now]
This does not work as timestamp is in milliseconds and now produces strings like 2001-01-01 13:00:00
Is it possible to achieve this with a cast or something?
I read about range queries and date math, but did not find anything.
It's easy to compute the timestamp in milliseconds for now and now-24h so why not do it in your application logic and build the query out of those values?
For instance (in JS),
const now = new Date().getTime();
const now24h = now - 86400000;
const query = `timestamp:[${now24h} TO ${now}]`;
query would contain the following value:
timestamp:[1647785319578 TO 1647871719578]
UPDATE:
PS: I might have misunderstood the initial need, but I'm leaving the above answer as it might help others.
What you need to do in your case is to change your mapping so that your date field accepts both formats (normal date and timestamp), like this:
PUT your-index/_mapping
{
"properties": {
"timestamp": {
"type": "date",
"format": "date_optional_time||epoch_millis"
}
}
}
Then you'll be able to query like this by mix and matching timestamps and date math:
GET test/_search?q=timestamp:[now-24h TO 1645825932144]
and also like this:
GET test/_search?q=timestamp:[1645825932144 TO now]

Get every round hour from Firestore

I have a data stored in Firestore, the data add to Firestore every second, so in 24 hours I have 1440 documents (24 * 60), I want to fetch only round hour from the Firestore for show it on a Graph, how can I get only round hour from Firestore?
First of all, you will have to store the firestore documents with a timestamp property and then query the documents with the timestamp value which gives a rounded hour using DateTime and DateFormat APIs of flutter.
Once you've got a timestamp back from Firestore, something like :
Timestamp(seconds=1560523991, nanoseconds=286000000)
You can get only rounded hour from the timestamp value using 2 ways :
You need to parse it into an object of type DateTime:
DateTime myDateTime = (snapshot.data.documents[index].data['timestamp']).toDate(); // prints 2020-05-09 15:27:04.074
This will return your Firestore timestamp in the dart's DateTime format. In order to convert your DateTime object you can use DateFormat class from the intl package. You can use your obtained DateTime object to get the format of your choice like this:
Possible Solution 1 :
DateFormat.Hm().format(myDateTime); //prints 15.27
So the query should look for documents with:
DateFormat.m().format(myDateTime) to be “00” as
DateFormat.m() returns minutes and if minutes == 00 then the timestamp is rounded to the nearest hour.
Possible Solution 2 :
Convert timestamp into timestring using :
Let TimeString = snapshot.data.documents[index].data['timestamp']).toDate().toString() // prints ‘2019-12-28 18:48:48.364’
Let time = TimeString.split(“ “)[1] // prints 18:48:48.364
To check if the minutes is “00” :
if time.substring(3,5) == “00”, then it's a rounded hour. //here it is 48
You will have to put these timestamp conversion logics and then query as I mentioned for the rounded hour timestamp. There are no readymade available functions/methods to get the firestore documents with rounded hours.
Firestore supports "IN" Queries.
Store as Timestamp, and try with following
const roundhour1 = new Date('2021-10-01T01:00:00.000z');
const roundhour2 = new Date('2021-10-01T02:00:00.000z');
And then write the query like below:
database.collection("collectionName").where("fieldName", "in", ["roundhour1", "roundhour2"]);
You can have up to 10 values (roundhourX) to check "IN" of, so need to fire 3 queries to get all 24 hours data.

mongodb difference in time

How can i filter database entries that have a datetime less than 60min in the past?
I tried some date operations as follows in mongodb with two fields timestamp and marketstartime that are of type date in all my documents:
{"$subtract": ["$timestamp", "$marketstartime"]}
but it returns always null for that operation. Why?
My timestamp and marketstartime entries in the db are in date type and look as follows, this should be correct:
2017-12-23 12:00:00.000Z
The actual question I’m trying to solve: How can I get all entries that have a timestamp less than 60 min in the past from now?
A query can composed for documents with timestamp value set less than 60 minutes ago.
from datetime import datetime, timedelta
query = {
'$timestamp': {
'$lt': datetime.now() + timedelta(minutes=-60)
}
}
cursor = db.collection.find(query)

How to save time in the database in Go when using GORM and Postgresql?

I'm currently parsing a time string and saving it to the db (Postgresql):
event.Time, _ := time.Parse("3:04 PM", "9:00 PM")
// value of event.Time now is: 0000-01-01 21:00:00 +0000 UTC
db.Create(&event)
It's giving me this error: pq: R:"DateTimeParseError" S:"ERROR" C:"22008" M:"date/time field value out of range: \"0000-01-01T21:00:00Z\"" F:"datetime.c" L:"3540"
event.Time⁠⁠⁠⁠'s type is time.Time.
I also tried setting event.Time's type to string and using time data type in postgresql:
type Event struct {
Time string `gorm:"type:time
}
But now I'm getting an error when fetching records in the db:
sql: Scan error on column index 4: unsupported driver -> Scan pair: time.Time -> *string
Investigated this issue further. Currently, there's no support in GORM for any Date/Time types except timestamp with time zone
See this part of code from dialect_postgres.go:
case reflect.Struct:
if _, ok := dataValue.Interface().(time.Time); ok {
sqlType = "timestamp with time zone"
}
So basically I see two options for you:
Either use varchar(10) in DB, and string in Go, an simply save it as "9:00 PM" (where 10 is some number that suits you)
Or use timestamp with time zone in DB, time.Time in Go, and format your date part as a constant date, 01/01/1970, for example:
time.Parse("2006-01-02 3:04PM", "1970-01-01 9:00PM")
In that case you'll have to omit the date part in your presentation, but if you plan to select by date range, that could work better for you.
You can set an arbitrary database-specific type with Gorm using sql tag
type Event struct {
Time time.Time `sql:"type:timestamp without time zone"`
}
When updating the DATETIME field in SQL, the Go string must be in this format: time.Now().Format(time.RFC3339).
From Postgres perspective the error stems from there being no year 0000. If you don't the date you may just be able to add 1 year to the converted timestamp giving '0001-01-01T21:00:00+00' which is a valid Postgres timestamp.
select '0000-01-01T21:00:00+00'::timestamptz at time zone 'UTC'
ERROR: date/time field value out of range: "0000-01-01T21:00:00+00"
Gives he same error. And just as a demonstration 1 day before 0001-01-01 gives:
select '0001-01-01T21:00:00+00'::timestamptz at time zone 'UTC' - interval '1 day' "day_before_1/1/1";
--day_before_1/1/1
--0001-12-31 21:00:00 BC

Query mongo on timestamp

I want to query Mongo based on timestamp. Follwing is the field in mongo.
"timestamp" : "2016-03-07 11:33:48"
Books is the collection name and below is my query for time period of 1 minute:
db.Books.find({"timestamp":{$gte: ISODate("2016-03-07T11:33:48.000Z"), $lt: ISODate("2016-03-07T11:34:48.000Z")}})
Also is there any alternative like I don't have to give greater and lower limit on timestamp. But query based time interval mentioned. Something like, if present timestamp is TS = "2016-03-07T11:33:48.000Z" then query should be between TS and TS + 1 minute rather than explicitly mentioning timestamp. Something like adding 1 minute to present timestamp
db.Books.find({"timestamp":{$gte: "2016-03-07 11:33:48", $lt: "2016-03-07 11:34:48"}})
ISODate is not required here