Aggregation query in MongoDB - mongodb

I'm looking to write a pretty straightforward aggregation query in MongoDB, but struggling with a certain part.
What I would like to do is pull the sum of all records within the last 7 days grouped by day. It's easy enough to define the date 7 days ago as UTC, but I'd like to do it programmatically so I don't need to work out the UTC date everytime. For instance instead of 1341964800 i'd like to specify something like date() - 7 days.
Here's the current aggregation function I have which works:
db.visits_calc.group(
{ key:{date:true},
cond:{date:{$gt:1341964800}},
reduce:function(obj,prev) {prev.csum += obj.total_imp},
initial:{csum:0}
});
Thanks in advance!

You can perform arithmetic on the milliseconds timestamp returned by Date.now() to find the appropriate timestamp for 7 days ago. You need to subtract the number of milliseconds in 7 days (1000ms/s, 60 s/min, 60min/hr, 24 hrs/dy, 7dys/wk).
var weekAgo = Date.now() - (1000*60*60*24*7);
db.visits_calc.group(
{ key:{date:true},
cond:{date:{$gt:weekAgo}},
reduce:function(obj,prev) {prev.csum += obj.total_imp},
initial:{csum:0}
});

Related

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.

I need help understanding this date format [duplicate]

This question already has answers here:
Converting Double to DateTime?
(5 answers)
Closed 3 years ago.
I have a csv file with a date column and I am having trouble trying to figure out the format in which this date is in.
I have tried several timestamp converters and none of them seem to give me the accurate date.
The dates should all range within 2017.
Excel store dates and times as a floating point number as days since 1900/01/01 00:00:00. So 42954.49986111111 represents 2017-08-07 11:59:48.0000000.
.Net can already understand this "format":
DateTime.FromOADate(42954.49986111111);
Looks like this is days from 1900, so to get timestamp you should add this value to 1900/01/01 timestamp multiplying on 1000 * 24 * 60 * 60
It should work
const d = Date.UTC(1900, 1, 1) + 24 * 3600 * 1000 * 42982
console.log(new Date(d).toString())
I think it is any date formate.
moment(42954.4998611111).format('MMMM Do YYYY, h:mm:ss a')
"January 1st 1970, 5:30:42 am"

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)

Find all records older than one year

I have a collection named "listenedMessage" in my MongoDb and it has a field called "timeReceived"
How do I find all records which are older than one year based on the "timeReceived" field?
Based on #Puneet Singh's comment I've came to a solution which retrieves all the records having "timeReceived" field older than a particular month.
function addMonths(date, months) {
date.setMonth(date.getMonth() + months);
return date;
}
db.listenedMessage.find({"timeReceived" : {$lt: addMonths(new Date(), -1)}}).count(); //this will give all the records having timeReceived field older than a month from today

Designing a database for querying by dates?

For example, I need to query the last 6 months by the earliest instance for each day (and last day by earliest instances in each hours, and last day by minutes). I was thinking of using MongoDB and having a nested structure like
year:{ month:{ day: { hour: { minute: [array of seconds]
But to get the first instance I would have to sort the array which is costly. Is there an easier way?
Would be better just to have a date field.
And query to be something like:
find(date: {$gt : 'starting_date', $lt : 'ending_date'})