Find document with array that has all and only the elements passed in the query array but in a shuffled order

I’d like to know if there is a way to find a document that has an array that includes all and only the elements passed in the query’s array. I know i could use {members: [id1, id2]} or (with the $all operator) but what if i the elements order is not the same?

Basically if the document has {members: [1, 2]} i want to be able to find it passing [2, 1] to the query, but it shouldn’t return the document if the query’s array includes any other number. The arrays should be the same except for the order.

Test if the $size of $setIntersection is the same as members.

1 Like

That seems a good approach but how would i combine the $all and $size operators? I think i need to use aggregations pipelines but I might be wrong as I tried and it didn’t work.

It is not

since I mentioned

I believe too since $setIntersection seems to be only available in aggregation.

Shared what you tried. You might be closer to a solution than you think.

While I was looking for $setIntersection examples to share, I discover $setEquals which would be a more direct way to do that compared to $size of $setIntersection.

And while I was writing I thought a way you can do it with $all and $size.

array_variable = [ 2 , 1 ]
collection.find( { "members" : { "$all" : array_variable , "$size" : array_variable.size() } }

$setIntersection and $setEquals are not what i’m looking for, since the first one just returns documents with arrays that have elements in common and the second one returns arrays that have the same elements in other fields.

This is exactly what i tried

This is way I wrote

If the $size of $setIntersection is the same as the size of the original array then the intersection contains all the elements.

As for $setEquals, according to the documentation I linked:


Compares two or more arrays and returns true if they have the same distinct elements and false otherwise.

$setEquals has the following syntax:

{ $setEquals: [ <expression1>, <expression2>, ... ] }

The arguments can be any valid expression as long as they each resolve to an array. For more information on expressions, see Expressions.

So I really do not understand what you mean by


is really what you tried, then I should have work because it does:

{  _id:0,  members: [  1,  2  ] }
{  _id:1,  members: [  1,  2,  3 ] }
array_variable = [ 2 , 1 ]
/* note that in JS it is array_variable.length rather than array_variable.size() like I originally wrote */
c.find( { "members" : { "$all" : array_variable , "$size" : array_variable.length } } )
{  _id:0,  members: [  1,  2  ] }