I am trying to find documents where any or all nested array elements must contain at least the values provided. This can normally be achieved easily with the $all
operator. For example here:
[
{
"words": [ "Hello", "World", "!"],
"wordArrays": [
["Hello", "World", "!"],
["The", "Sun", "Shines"]
]
}
]
The query {words: {$all: ["Hello", "World"]}}
correctly matches because both are contained and {words: {$all: ["Hello", "I do not exist"]}}
does not match. So far so good.
If you attempt the same for the nested arrays this stops working altogether. {"wordArrays.0": {$all: ["Hello", "World"]}}
does not match. I have found similar questions why on nested arrays all the operators start to fail but no one ever can explain why and they just use $elemMatch
. But I do not know how I would translate my “all values must be in the array” to an $elemMatch
. And then how I would say
-
ANY of the
wordArrays
must contain “Hello” and “World” → would match -
ALL of the
wordArrays
must contain “Hello” and “World” → would not match the data
I have prepared this little playground with the data in the hopes somebody knows how to achieve this.
Playground
I would prefer if this could be solved all within the Find() stage, but if operations like this suddenly require the aggregation pipeline I am fine with that too.
My approach for ANY match does not return any matches, and I do not understand why {wordArrays: {$elemMatch: {$all: ["Hello", "World"]}}}
. I read it as wordArrays
: does any element match: array contains “Hello” and “World”. And that should have matched the document
Thank you!