I'm using MongoDB 4.2 and I'm looking for a way to remove all elements from a subarray if it doesn't match a certain condition using an aggregation stage that is compatible with a change streams. The compatible stages are:
For example consider that we have a collection, users, containing documents in this format:
{ "name" : "John Doe",
"access": [
{ "level" : "Gold", "rating" : 3.2 },
{ "level" : "Silver", "rating" : 2.1 },
{ "level" : "Gold", "rating" : 4.2 }
]
}
I'd like to use one, or a combination, of the compatible aggregation stages to remove elements in the "access" array that doesn't match a filter such as { $elemMatch : { "level" : "Gold" } }
. I'd like the resulting document to look like this:
{ "name" : "John Doe",
"access": [
{ "level" : "Gold", "rating" : 3.2 },
{ "level" : "Gold", "rating" : 4.2 }
]
}
Is it possible to do this in MongoDB?
You can use $addFields
/ $set
together with $filter
db.collection.aggregate({
$set: {
access: {
$filter: {
input: "$access",
cond: { $eq: ["$$this.level", "Gold"] } // your condition expression
}
}
}
})
If you want to update existing documents, you can do this with the update pipeline as follows
db.test.updateMany({
access: { $elemMatch: { level: { $ne: "Gold" } } }, // find elements that does not match your condition
[{
$set: {
access: {
$filter: {
input: "$access",
cond: { $eq: ["$$this.level", "Gold"] } // your condition expression
}
}
}
}]
)