I need to count the number of matching elements between 2 arrays using MongoDB filter aggregation. I tried using $eq and $setIntersection on the condition field of filter but the number of matching elements return just 1 even if all 4 elements match.
Here’s the user scenario:
- User enters 4 digit number: 1, 2, 3, 4
- It should check the number of matches it has with the numbers on the backend. In this case, 1, 2, 3, 4 also.
- Should return 4 matches.
Right now, it’s just returning 1 on my query. If there’s a mismatch, like the user enters 1, 2, 3, 5 then it should return 3 matches.
Here’s the query:
db.collection.aggregate({
$match: {
"entries.numbers": {
$in: [
1,
2,
3,
4
]
}
}
},
{
"$addFields": {
"matchingCount": {
$size: {
$filter: {
input: "$entries",
as: "e",
cond: {
$eq: [
"$$e.numbers",
[
1,
2,
3,
4
]
]
}
}
}
}
}
})
Here’s the playground link: https://mongoplayground.net/p/5YSDOL6LwGs
2
Answers
1. Wrt
If you remove the
$size
part from the$addFields
stage, you’ll see thatmatchingCount
is actually a list of one object, so$size
returns 1.Also, changing the order of
[ 1, 2, 3, 4 ]
anywhere in the pipeline or the gives no match at all. So you really should just be using sets.2. In your other question, you’ve given an example db where all other
entries
are together in one document, as an array of objects.So if you want all the matching entries which have at least one correct guess:
Input collection, with order of numbers being different from the "winning"
[1, 2, 3, 4]
:Query:
Result with my example db:
Mongo Playground
And here’s a combined-stages version of that, along with
the playground:
Try this query :