Given the following collection
db.playground.insertMany([
{ "id": 1, "tags": [{"t": "T1", "v": "t11", "c": 1 }, {"t": "T2", "v": "t12"}, {"t": "T3", "v": "t13"}]},
{ "id": 2, "tags": [{"t": "T1", "v": "t21", "c": 2 }, {"t": "T2", "v": "t22"}, {"t": "T3", "v": "t23"}]},
{ "id": 3, "tags": [{"t": "T1", "v": "t22", "c": 2 }, {"t": "T2", "v": "t21"}, {"t": "T3", "v": "t33"}]},
])
How could I filter the tags array for each document so that they only contain:
- The tags with t = T2 or t = T3 if there’s at least one tag in the same array with t = T1, v = t21 and c = 1
- The tags with t = T1 or t = T3 if there’s at least one tag in the same array with t = T1, v = t21 and c = 2
This is my current attempt at it, but there are some issues with it:
- I don’t understand why the predicate
{ $eq: ["$tags.v", "t21"] }
doesn’t work - I don’t understand why this requires square brackets
{ $eq: ["$tags.c", [1]]}
and it doesn’t work when I use NumberInt like here{ $eq: ["$tags.c", NumberInt(1)] }
- How can I make sure that c and v belong to the same tag, my current example also returns the 3rd entry which meets one condition on one tag and the second on the other.
db.playground.find({},
{
id: 1,
tags: {
$filter: {
input: "$tags",
as: "tag",
cond: {
$or: [
{ $and: [
// { $eq: ["$tags.v", "t21"]}, // Why does this not work
{ $eq: ["$tags.c", [1]]}, // Why does this work as an array?
{ $in: ["$$tag.t", ["T2", "T3"]] }
]
},
{ $and: [
// { $eq: ["$tags.v", "t21"]}, // Why does this not work
{ $eq: ["$tags.c", [2]]}, // Why does this work as an array?
{ $in: ["$$tag.t", ["T1", "T3"]] }
]
}
]
}
}
}}
)
Playground