I have a collection with a nested array of subdocuments. I’d like to filter out the subdocuments in this nested array that have the field status: REMOVED, and then return the original document unchanged aside from the filtered subdocument array. I have this working in the following aggregate pipeline:
db.getCollection('inventory').aggregate([
{
$match: {
updatedat: {
$gte: ISODate("2021-05-10T12:00:00Z"),
$lte: ISODate("2021-05-11T12:00:00Z")
}
}
},
{ $unwind: "$sizes" },
{
$match: {
"sizes.status": { $ne: "REMOVED" }
}
},
{
$group: {
_id: {
item: "$item",
price: "$price",
updatedat: "$updatedat",
fees: "$fees"
},
sizes: { $push: "$sizes" }
}
},
{
$project: { _id: 0, sizes: 1, item: "$_id.item", price: "$_id.price", updatedat: "$_id.updatedat", fees: "$_id.fees" }
}
Here is an example document in my collection:
{
"_id" : ObjectId("60996db251b4a0b97ee405ba"),
"item" : "A",
"price" : NumberDecimal("80"),
"updatedat" : ISODate("2021-05-10T12:00:00.000Z"),
"fees" : {
"texttext" : "sold in!",
"taxes" : [
{
"type" : 1.0,
"description" : "QC/CA#1234"
},
{
"type" : 2.0,
"description" : "QC/CA#2231"
}
]
},
"sizes" : [
{
"size" : "S",
"status" : "AVAILABLE"
},
{
"size" : "M",
"status" : "REMOVED"
},
{
"size" : "L",
"status" : "AVAILABLE"
}
]
}
This returns what I need, but managing each root level field by grouping them inside _id, and then projecting them in the final stage is tedious. This is also a test dataset, in reality the documents I’ll be manipulating are much more complex.
I was wondering if there was a better way to handle this than my solution above.