Reputation: 309
I have the following model:
{
"_id" : ObjectId("...some id"),
"lessons" : [
{
"date" : ISODate("2019-09-23T16:00:00.000+02:00"),
"subject" : [
"Javascript",
"Order"
],
"price" : 60
},
{
"date" : ISODate("2019-09-24T16:00:00.000+02:00"),
"subject" : [
"Javascript"
],
"price" : 120
}
]
}
I would like to filter "lessons" array based on value in nested "subject" array. Filter i mean remove whole object from array "lessons" if for example value in nested array "subject" is not equeal to value "Order".
Expected output (remove object, becasuse nested array contains "Order" value):
{
"_id" : ObjectId("...some id"),
"lessons" : [
{
"date" : ISODate("2019-09-24T16:00:00.000+02:00"),
"subject" : [
"Javascript"
],
"price" : 120
}
]
}
I've tried use $filter pipeline but it overwrite whole array "lessons".
db.students.aggregate([
{
$project: {
"lessons": {
$filter: {
input: "$lessons.subject",
as: "subject",
cond: {
$ne: [
"$$subject",
"Order"
]
}
}
}
}
},
]);
Upvotes: 1
Views: 93
Reputation: 3529
What we can do here is:
$unwind
on the field lessons
to treat them as individual documents.$match
on subjects
field (array) with the condition.$group
by _id
and push lessons
back via
$push
Query:
db.collection.aggregate([
{ $unwind: "$lessons" },
{ $match: { "lessons.subject": { $ne: "Order" } } },
{
$group: {
_id: "$_id",
lessons: { $push: "$lessons" }
}
}
]).pretty();
Output:
{
"_id" : ObjectId("5d6d0d401ce4f18674c11053"),
"lessons" : [
{
"date" : ISODate("2019-09-24T14:00:00Z"),
"subject" : [
"Javascript"
],
"price" : 120
}
]
}
Upvotes: 1