$sum function to do sum of hours and min - node.js

I have one user who has multiple tasks with hours and minutes. which I stored in milliseconds
user's tasks schema
tasks:{
userId: String //getting from the session(storing the task schema)
time:{type: "number"}
}
User's input like this
time:{
hrs: 10,
min: 45
}
I converted the user input in milliseconds using the date.getTime() function by setting the hours and minutes.
Which will later be stored as milliseconds in the schema.
The output will be ( suppose there are multiple tasks) 10 + 10 (the final output should be
20hrs
So I Want to do the sum of all the multiple hours based on a specific user(userId) stored in
tasks
Should I Use the Aggregation method for this problem?

Related

How do I query the dates in mongodb such that the entries with less than 1 hour difference is removed?

MongoDB collection
I have this collection. I want to query entries so that either one of key "2" or "3" would be removed because the createdAt entries have a difference less than 1 hour. What would be the query?
Query
uses $dateTrunc with unit hour, that means keep the date as it is, but make zero all the left after the date
group by that trunc date => dates with same hour are in the same group
keep only one of them
*query doesn't work with difference, it works by same hour, for example 1:01 is the same with 1:59 but 1:59 is not same group with 2:01
*difference is complicated i think, because 2 dates can have difference 1 hour, and be in different days, months, or even years,
also we have to decide which ones to keep, in case of chains of dates.
Test code here
aggregate(
[{"$group":
{"_id":{"$dateTrunc":{"date":"$createdAt", "unit":"hour"}},
"doc":{"$first":"$$ROOT"}}},
{"$replaceRoot":{"newRoot":"$doc"}}])
You can use $gt query. See the document here
And here is a code example. Just change the places with your property, which is createdAt in your scenario.
let user = await User.deleteMany({
createdAt: { $gt: Date.now() - 3600000 } // 3600000 means 1 hour in millisecond
});
// Rest of your code

Sequential ledger-like entries in NodeJS with Async/ Await

I'm designing an accounting/ book-keeping application and my table has the following columns -
Transaction ID
Transaction Details
Amount
Closing Balance
All the transactions are fed to NodeJS function one-by-one through a queue
However, while saving each transaction, I have to fetch the previous transaction to get the last closing balance and add current transaction amount to the same to get the new closing balance
But I have to use async/await to fetch previous transaction so the event loop is free for a few milliseconds during which the function receives a new transaction event from the user. This is causing a lot of inconsistencies with the data as sometimes 2 rows with the same closing balance are inserted.
const prevTransaction = await Transaction.findOne({
where: { userId },
order: [['createdAt', 'DESC']]
})
await Transaction.create({
userId,
amount,
closingBalance: prevTransaction ? prevTransaction.closingBalance + amount : amount,
transactionDate
})
Now if the system receives a lot of events in bulk then there could be some inconsistencies in data due to the gap between GET & INSERT query.
In some scenarios, this is the data that's inserted
ID
Amount
ClosingBalance
1
20
20
2
20
40
3
20
40
4
10
50
5
20
60
When ideally it should be -
ID
Amount
ClosingBalance
1
20
20
2
20
40
3
20
60
4
10
70
5
20
90
Any particular way I could tweak the above code to get the sequential effect?
This is the reason I'm using a BullJS queue is so that transactions are processed one-by-one. But this issue still persists because of the 2 await calls.
I have temporarily solved this problem by pausing the job queue if any transaction is being processed and resuming it once the transaction is inserted - link
Would love to hear about any alternate approaches since this approach is relying on a third-party library.

how to convert milliseconds into HH:MM:SS format in mongodb(3.4 version)

I am projecting a field as i want the difference between DateOfOcurrance and current time. Then I want to compare the diff_time field with one time which is in String format(HH:MM:SS) as I want those documents which have less than 15mins diff_time, but not getting.
{$project: {diff_time:{ $subtract: ["$DateOfOcurrance", new Date("2020-02-14")]}}},
{"$match": {"diff_time": { "$lt": "00:15:00" }}}
Dates are stored as the number of milliseconds since epoch. When you subtract one date from another, you get a NumberLong containing the difference in milliseconds.
To find differences less than 15 minutes, use:
{"$match": {"diff_time": { "$lt": 900000 }}}
(900000 = number of milliseconds in 15 minutes)

mongodb aggregate documents by dates nearest to specific hour/minute in day

I have documents in my mongodb, this documents have event field - this fild type is date. The year, month , day, does not matter, means only the time during day. I want the cron script,every day, to aggregate from mongodb the documents with the event (date typed) field to be in nearest 10 minutes (to the script calling date). How to implement it in right way?
db.mytable.find(
{
"event": {
$gt: new Date(new Date().getTime() - (10 * 60 * 1000))
}
})
This query will find all documents that have an "event" property with a value within the past 10 minutes. new Date() without arguments returns a Date representing "right now". We pull the numeric epoch time in milliseconds from that and subtract 10 minutes. More specifically, we subtract (10 minutes * 60 seconds per minute * 1000 milliseconds per second), so that we convert to the correct units. We then use that value to construct another new Date(...), and this is the one that goes into the $gt (greater-than) filtering condition.
You mentioned a need for "aggregation". If so, then this same query can also be used within any Aggregation Pipeline that you need.

Updating a Duration Field by Plugin

Has anyone had to update a Duraton field from within a plugin?
On the UI it is fairly intelligent, you can type
5 minutes
7 //defaults to minutes
3 hours
And it will workout what you need.
Assuming the field is called new_foo, what value should I assign? Int?
var e = new Entity("new_bar");
e.Attributes("new_foo", 5);//5 minutes?
Double?
var e = new Entity("new_bar");
e.Attributes("new_foo", 5.00);//5 minutes?
Other ideas?
Duration is a format for the Whole Number type, so by code you need to set an Int32 value (in this case not negative or it will throw an exception)
The value is always considered in minutes, so if you want to put 3 hours you need to set the field value to 180 (60 minutes x 3 hours), 1 day is 1440 (60 minutes x 24 hours) and so on.
By interface you can set using decimals, but it's always a representation of an integer value (for example 1.5 hours equals 90 minutes)

Resources