I have used mongoose nodejs to get the week wise data. I have data stored in UTC format, the sample data will be like below
Steps: {
"quantity": 25,
"duration": 100,
"endTime": "2023-05-18 01:25:53 +0000",
"startTime": "2023-05-18 01:25:52 +0000"
},
leadId: 10
From the set of data I am trying to get the week wise data while user pass timezone as IST, I need to get the data. For example, if user request data from 01-05-2023 to 31-05-2023 I need to query based on startTime from 30-04-2023 18:30:00 to 30-05-2023 18:29:59 (IST is +05:30).
I am trying achieve with following aggregate query
activities.aggregate([
{ '$addFields': { date: { '$toDate': '$Steps.startTime' } } },
{
'$match': {
Steps: { '$ne': null },
date: { '$gte': "2023 - 04 - 30T18: 30: 00.000Z", '$lte': "2023 - 05 - 29T18: 29: 59.000Z" }, leadId: 38047
}
},
{
'$group': {
_id: { startTime: '$Steps.startTime', endTime: '$Steps.endTime' },
doc: { '$last': '$$ROOT' }
}
},
{
'$group': {
_id: { '$week': '$doc.date' },
quantity: { '$sum': { '$convert': { input: '$doc.Steps.quantity', to: 'double', onNull: 0, onError: '' } } },
duration: { '$sum': { '$convert': { input: '$doc.Steps.duration', to: 'double', onNull: 0, onError: '' } } }
}
},
{ '$group': { _id: null, docs: { '$push': '$$ROOT' } } },
{
'$project': {
docs: {
'$map': {
input: { '$range': [{ '$week': "2023 - 04 - 30T18: 30: 00.000Z" }, { '$week': "2023 - 06 - 04T00: 00: 00.000Z" }] },
as: 'weekNumber',
in: {
'$let': {
vars: { index: { '$indexOfArray': ['$docs._id', '$$weekNumber'] } },
in: {
'$cond': {
if: { '$eq': ['$$index', -1] },
then: { _id: '$$weekNumber', quantity: 0, duration: 0 },
else: { '$arrayElemAt': ['$docs', '$$index'] }
}
}
}
}
}
}
}
},
{ '$unwind': '$docs' },
{ '$replaceRoot': { newRoot: '$docs' } },
{
'$project': {
_id: '$_id',
quantity: { '$ifNull': ['$quantity', 0] },
duration: { '$ifNull': ['$duration', 0] },
weekOfMonth: 1
}
}
])
Here I am expecting query to run for current week from 27-05-2023 18:30:00 to 03-05-2023 18:29:59. But query is running for the current week from 28-05-2023 00:00:00 to 03-05-2023 11:59:59. Not converted datetime inside week range, it took data basis only. But I am expecting this to run based on date time with data conversion.
2
Answers
I have edited the query like below
You should never store date values as stings, it’s design flaw. Store always proper
Date
objects.With
Date
values, the$match
could be simplyYou can group directly by week:
And to fill missing values with 0, I would suggest
$densify
and$fill
With only one input document and without expected result, it is a bit difficult for me to provide the full aggregation pipeline. There would be too many options.