Reputation: 117
I've been looking to get data for the last n days. For example, I want to just all the data of the last 3 days. After implementing a solution from another question in StackOverflow I'm not getting all the documents. I am only getting one document. If I want to see the documents for the last 3 days it is only showing data for one particular day.
Here's my Schema:
dayWiseClicks: [
{
date: {
type: Date,
},
dailyClicks: {
type: Number,
default: 0,
},
},
],
Here's the data I have before performing the query:
{
"_id": {
"$oid": "61eff4bacf8335c7013f8065"
},
"dayWiseClicks": [
{
"dailyClicks": 3,
"_id": {
"$oid": "61eff5db5dca56cae4530db2"
},
"date": {
"$date": "2022-01-24T18:00:00.000Z"
}
},
{
"dailyClicks": 4,
"_id": {
"$oid": "61eff60b5dca56cae4530db6"
},
"date": {
"$date": "2022-01-25T18:00:00.000Z"
}
},
{
"dailyClicks": 2,
"_id": {
"$oid": "61eff64a5dca56cae4530dba"
},
"date": {
"$date": "2022-01-26T18:00:00.000Z"
}
},
{
"dailyClicks": 7,
"_id": {
"$oid": "61f60ce51f14b01f8f5be936"
},
"date": {
"$date": "2022-01-29T18:00:00.000Z"
}
},
{
"dailyClicks": 11,
"_id": {
"$oid": "61f7b1d3931b0f8bc33703d4"
},
"date": {
"$date": "2022-01-30T18:00:00.000Z"
}
},
{
"dailyClicks": 8,
"_id": {
"$oid": "61f8bdf63cc3a51b72474cb9"
},
"date": {
"$date": "2022-01-31T18:00:00.000Z"
}
},
{
"dailyClicks": 7,
"_id": {
"$oid": "61fba7159692624ce8ea04d6"
},
"date": {
"$date": "2022-02-02T18:00:00.000Z"
}
}
],
}
In theory, if I want to see the last 3 days of data. It should be showing data of 31st Jan, 2nd February but It is only showing Data of 31st January.
Here's the data I am getting:
{
"message": "Url By ID",
"result": {
"_id": "61eff4bacf8335c7013f8065",
"dayWiseClicks": [
{
"dailyClicks": 8,
"_id": "61f8bdf63cc3a51b72474cb9",
"date": "2022-01-31T18:00:00.000Z"
}
]
}
}
Here's my Code:
exports.lastNDays = async (req, res) => {
try {
const url = await URL.findById(
{ _id: req.params.id },
{
dayWiseClicks: {
$elemMatch: {
date: {
$gte: moment().add(-3, "days"),
},
},
},
}
)
return res.status(200).json({
message: "Url By ID",
result: url,
});
} catch (error) {
return res.status(404).json({ error: error.message });
}
};
Can any one tell me exactly where I am making the mistake?
Upvotes: 0
Views: 115
Reputation: 7588
If your dayWiseClicks
are in natural date-ascending order (and it seems that way), then to generically capture the last 3 days of any sequence of dates can be done with $slice
:
db.foo.aggregate([
{$addFields: {dayWiseClicks: {$slice: ["$dayWiseClicks", -3]}}}
]);
You can prepend $match
stages as detailed in previous answers.
NOTE: Coming up in v5.4 (available now in 5.2 rapid release for MongoDB Atlas) is the long-awaited sortArray
operator. If the dayWiseClicks
was not in date order, then making it that way and finding the last 3 dates is freshingly simple:
db.foo.aggregate([
{$addFields: {dayWiseClicks: {$slice: [{$sortArray:{input: "$dayWiseClicks", sortBy: {"date":1}}, -3]}}}
]);
Similarly, to get the last 3 dates but in descending order:
db.foo.aggregate([
{$addFields: {dayWiseClicks: {$slice: [{$sortArray:{input: "$dayWiseClicks", sortBy: {"date":-1}}, 3]}}}
]);
Upvotes: 0
Reputation: 10737
The aggregation->$filter option seems more suitable for the task , example:
db.collection.aggregate([{
$match: {
"_id": {
"$oid": "61eff4bacf8335c7013f8065"
}
}
},
{
$project: {
dayWiseClicks: {
$filter: {
input: "$dayWiseClicks",
as: "item",
cond: {
$gte: [
"$$item.date",
{
"$date": "2022-01-30T18:00:00.000Z"
}
]
}
}
}
}
}
])
Explained:
Upvotes: 1