Right now, it's not possible to use the $in operator in the $filter array aggregation operator.
Let's say this is the document schema:
{
_id: 1,
users: [
{
_id: 'a',
accounts: ['x', 'y', 'z']
},
{
_id: 'b',
accounts: ['j','k','l']
}
]
}
I want, using aggregate
, to get the documents with filtered array of users
based on the contents of the accounts
array.
IF the $in
would work with the $filter
operator, I would expect it to look like this:
db.test.aggregate([
{
$project: {
'filtered_users': {
$filter: {
input: '$users',
as: 'user',
cond: {
$in: ['$$user.accounts', ['x']]
}
}
}
}
}
])
and return in the filtered_users
only the first user since x is in his account.
But, as I said, this doesn't work and I get the error:
"invalid operator '$in'"
because it isn't supported in the $filter
operator.
Now I know I can do it with $unwind
and using regular $match
operators, but then it will be much longer (and uglier) aggregation with the need of using $group
to set the results back as an array - I don't want this
My question is, if there is some other way to manipulate the $filter
operator to get my desired results.
To query if the array field contains at least one element with the specified value, use the filter { <field>: <value> } where <value> is the element value. To specify conditions on the elements in the array field, use query operators in the query filter document: { <array field>: { <operator1>: <value1>, ... } }
Use the $in Operator to Match Values This query selects all documents in the inventory collection where the value of the quantity field is either 5 or 15. Although you can write this query using the $or operator, use the $in operator rather than the $or operator when performing equality checks on the same field.
The $project takes a document that can specify the inclusion of fields, the suppression of the _id field, the addition of new fields, and the resetting of the values of existing fields. Alternatively, you may specify the exclusion of fields. Specifies the inclusion of a field.
Filter MongoDB Array Element Using $Filter Operator This operator uses three variables: input – This represents the array that we want to extract. cond – This represents the set of conditions that must be met. as – This optional field contains a name for the variable that represent each element of the input array.
Since $in
is not supported in aggregate operation for array, the alternative would be for you to use $setIsSubset
. For more information on this you can refer this link. The aggregate query would now look like
db.test.aggregate([
{
$project: {
'filtered_users': {
$filter: {
input: '$users',
as: 'user',
cond: {
$setIsSubset: [['x'], '$$user.accounts']
}
}
}
}
}])
This query will return only elements which have [x]
as a subset of the array in user.accounts
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With