Reputation: 391
Below is the document which has an array name datum
and I want to filter the records based on group by year and filter by the types and max date.
{
"_id" : ObjectId("5fce46ca6ac9808276dfeb8c"),
"year" : 2018,
"datum" : [
{
"Type" : "1",
"Amount" : NumberDecimal("100"),
"Date" : ISODate("2018-05-30T00:46:12.784Z")
},
{
"Type" : "1",
"Amount" : NumberDecimal("300"),
"Date" : ISODate("2023-05-30T00:46:12.784Z")
},
{
"Type" : "2",
"Amount" : NumberDecimal("340"),
"Date" : ISODate("2025-05-30T00:46:12.784Z")
},
{
"Type" : "3",
"Amount" : NumberDecimal("300"),
"Date" : ISODate("2021-05-30T00:46:12.784Z")
}
]
}
The aggregate Query I tried.
[{$group: {
_id :"$year",
RecentValue :
{
$sum: {
$reduce: {
input: '$datum',
initialValue: {},
'in': {
$cond:
[
{
$and:
[
{$or:[
{ $eq: [ "$$this.Type", '2' ] },
{$eq: [ "$$this.Type", '3' ] }
]},
{ $gt: [ "$$this.Date", "$$value.Date" ] },
]
}
,
"$$this.Amount",
0
]
}
}
}
}
}}]
the expected output would be which having the max date "2025-05-30T00:46:12.784Z"
{
_id :2018,
RecentValue : 340
}
Please let me know what mistake I did in the aggregate query.
Upvotes: 2
Views: 817
Reputation: 36104
You can get max date before $group
stage,
$addFields
to get document that having max date from, replaced $or
with $in
condition and corrected return value$group
by year
and sum Amount
db.collection.aggregate([
{
$addFields: {
datum: {
$reduce: {
input: "$datum",
initialValue: {},
"in": {
$cond: [
{
$and: [
{ $in: ["$$this.Type", ["2", "3"]] },
{ $gt: ["$$this.Date", "$$value.Date"] }
]
},
"$$this",
"$$value"
]
}
}
}
}
},
{
$group: {
_id: "$year",
RecentValue: { $sum: "$datum.Amount" }
}
}
])
Upvotes: 1