Get startedGet started for free

Filter Arrays using Distinct Values

1. Matching array fields

In this lesson, we'll learn more about how to query array fields and their structured values.

2. Array fields and equality

Here we see part of the laureates collection document for John Bardeen. He won two prizes, both in physics. Each prizes array in a laureate document contains subdocuments. Each subdocument has a category field. We can use dot notation to filter for and count laureates with a prize category equal to physics.

3. Array fields and equality, simplified

Here's a simpler example using a fictitious field. Let's imagine that laureate documents had an extra field, "nicknames". This field stores an array of string values. Let's now find all laureates with a nickname of "JB". We could use a filter document like this. The filter matches all documents that have at least one value in the "nicknames" array field equal to "JB". This notation is familiar. If "nicknames" was not an array, the filter would match for the field value being equal to "JB". Because "nicknames" is an array, the filter matches if any member of the array matches.

4. Array fields and operators

Let's go back to filtering on the real "category" field. This field is within subdocuments of the top-level "prizes" array field. As before, we can wrap filter document values with operators. For example, here we filter for laureates with a prize not in physics. Note that these documents may contain a prize subdocument with a category of physics. They need only also contain a prize subdocument with another category value. Another example. Here, we use the "in" operator to find laureates with at least one prize in these three categories. And here, we use the "not-in" operator to find laureates with at least one prize not in these three categories.

5. Enter $elemMatch

But what if we want to filter on more than one field within a prize subdocument? Let's try something like this to count laureates who won unshared prizes in physics. Hmm, that's not quite what we want. This filter matches prize subdocuments that have two and only two fields. No laureates have a prize subdocument that looks exactly like this. All prize subdocuments also have a year field, for instance. This next filter is better, but it's not quite what we want. This filter matches laureate documents satisfying two conditions. The first is that a prizes field has at least one subdocument with a "category" field equal to "physics". The second is that that a prizes field has at least one subdocument with a "share" field equal to "1". The prizes that match for a laureate could be different prizes. This is where the "element match" - or "elemMatch" - operator comes in. Finally, we count all laureates that have at least one unshared prize in physics. Within the "elemMatch" operation, as with any operation, we can continue to drill down. Operations can nest to make finer-grained queries. Here, we extend the last filter to include laureates only if they won a solo prize in physics before 1945.

6. Onward and array-ward!

Let's make sure you understand how to filter arrays with "elemMatch". We'll do this in concert with other operators. And we'll learn some Nobel prize statistics along the way.