MongoDB $elemMatch Query Operator: Introduction, Syntax and Usage

MongoDB provides us with many useful operators that can be used to perform any type of operation on the database regardless of whether the operation is straightforward or complicated.

We have already covered lots of MongoDB operators and yet the list is never-ending and that is why MongoDB stand over other non-relational databases.

In this article, we will be seeing a not-so-popular yet very important operator that can be used in many complicated situations. The operator name is $elemMatch operator. Let’s start with an easy introduction.

Also Read: $gt and $lt Operators in MongoDB

MongoDB $elemMatch Operator

The $elemMatch query operator allows us to match documents with an array field that contains at least one element that matches the specified query criteria.

Syntax:

db.collection.find({ field: { $elemMatch: { <query1>, <query2>, ... } } })

Parameters:

  • “collection” is the name of the collection where we are looking for the document,
  • “find” is the method we are using to query the documents,
  • “field” represents an array field within the documents,
  • “queryN” is the condition for filtering the selection.

Note: MongoDB doesn’t allow you to use the $where operator and the $text operator with the $elemMatch query operator.

Example 1: Using $elemMatch Operator for Matching Values in Arrays

Let’s now use the MongoDB $elemMatch to match documents with an array field that satisfies all specified queries.

1. Start up the MongoDB Server.

2. Pick a database to work with and move into it:

show dbs
use testGrades

3. Take a quick look at all of the documents inside a collection of that database:

> db.grades.find({})

{ _id: 1, name: "John Mendes", grades: [ 82, 85, 88, 90, 78 ] }

{ _id: 2, name: "Sofia Derulo", grades: [ 70, 75, 68, 65, 70 ] }

{ _id: 3, name: "Areesha Shaikh", grades: [ 86, 89, 93, 90, 88 ] }

{ _id: 4, name: "Grace Handles", grades: [ 55, 65, 63, 68, 70 ] }

{ _id: 5, name: "Rebecca Chism", grades: [ 82, 78, 80, 91, 75 ] }

{ _id: 6, name: "David Hudson", grades: [ 67, 70, 78, 74, 72 ] }

{ _id: 7, name: "Latonya Jacobson", grades: [ 80, 87, 84, 95, 81 ] }

{ _id: 8, name: "Luigi Markham", grades: [ 82, 73, 79, 80, 71 ] }

Following is the query using the $elemMatch query operator to match values in the “grades” array field to find out the nerds of the class:

db.grades.find( { grades: { $elemMatch: { $gte: 86, $lt: 100 } } } )

{ _id: 1, name: "John Mendes", grades: [ 82, 85, 88, 90, 78 ] }

{ _id: 3, name: "Areesha Shaikh", grades: [ 86, 89, 93, 90, 88 ] }

{ _id: 7, name: "Latonya Jacobson", grades: [ 80, 87, 84, 95, 81 ] }

Here “$gte: 86” specifies that the value must be greater than or equal to 86 and “$lt: 100” specifies that the value must be less than 100. The returned result has the documents with specified criteria.

Example 2: Using $elemMatch Operator for Matching Values in Embedded Documents

Let us grab an example from w3resource and understand how we can use the $elemMatch query operator to match values in embedded documents

Here’s what our sample data looks like:

{
        "_id" : ObjectId("5285bd678154c4747b705b4f"),
        "item_code" : "I001",
        "category" : [
                "boy",
                "girl"
        ],
        "description" : [
                {
                        "agegroup" : "3-5",
                        "flavour" : "chocolate",
                        "price" : 5
                },
                {
                        "agegroup" : "6-9",
                        "flavour" : "strawberry",
                        "price" : 6
                },
                {
                        "agegroup" : "10-13",
                        "flavour" : "mango",
                        "price" : 7
                }
        ]
}
{
        "_id" : ObjectId("5285bd808154c4747b705b50"),
        "item_code" : "I002",
        "category" : [
                "boy",
                "girl"
        ],
        "description" : [
                {
                        "agegroup" : "3-5",
                        "flavour" : "vanilla",
                        "price" : 3
                },
                {
                        "agegroup" : "6-9",
                        "flavour" : "lemon",
                        "price" : 6
                },
                {
                        "agegroup" : "10-13",
                        "flavour" : "mango",
                        "price" : 5
                }
        ]
}
{
        "_id" : ObjectId("5285bd8a8154c4747b705b51"),
        "item_code" : "I003",
        "category" : [
                "boy",
                "girl"
        ],
        "description" : [
                {
                        "agegroup" : "3-5",
                        "flavour" : "pineapple",
                        "price" : 5
                },
                {
                        "agegroup" : "6-9",
                        "flavour" : "mango",
                        "price" : 6
                },
                {
                        "agegroup" : "10-13",
                        "flavour" : "vanilla",
                        "price" : 5
                }
        ]
}

Following is the query using the $elemMatch query operator to match values in the “description” field which contains an array of embedded documents:

> db.table1.find( { "description": { $elemMatch: { "agegroup" : "3-5","price" : 5}}}).pretty();

{
        "_id" : ObjectId("5285bd678154c4747b705b4f"),
        "item_code" : "I001",
        "category" : [
                "boy",
                "girl"
        ],
        "description" : [
                {
                        "agegroup" : "3-5",
                        "flavour" : "chocolate",
                        "price" : 5
                },
                {
                        "agegroup" : "6-9",
                        "flavour" : "strawberry",
                        "price" : 6
                },
                {
                        "agegroup" : "10-13",
                        "flavour" : "mango",
                        "price" : 7
                }
        ]
}
{
        "_id" : ObjectId("5285bd8a8154c4747b705b51"),
        "item_code" : "I003",
        "category" : [
                "boy",
                "girl"
        ],
        "description" : [
                {
                        "agegroup" : "3-5",
                        "flavour" : "pineapple",
                        "price" : 5
                },
                {
                        "agegroup" : "6-9",
                        "flavour" : "mango",
                        "price" : 6
                },
                {
                        "agegroup" : "10-13",
                        "flavour" : "vanilla",
                        "price" : 5
                }
        ]
}

We can see that the $elemMatch operator matches the document with the exact specified criteria. As a result, we got the filtered documents. In this way, we have successfully learned how to use the $elemMatch query operator in MongoDB.

Read More: $each Operator in MongoDB

Conclusion

The $elemMatch operator is used when there is a need to filter multiple documents where at least one array element satisfies all specified queries. As per its behavior, it is mostly used for finding documents where a single array element meets multiple criteria. 

In this article, we share with you the most easy syntax for using the $elemMatch operator. We have also demonstrated its use using examples like filtering students with grades within a range and matching values in embedded documents. This will give you a good idea of how you can use the $elemMatch query operator for your MongoDB backed applications in the future as well.

Although this operator is useful in many places, it can be difficult to understand for beginners, so if you want to read an alternative, here is another article on the $in operator. Hope this article includes all the important information about the MongoDB $elemMatch operator.

Reference

$elemMatch (query) — MongoDB Manual

Aneesha S
Aneesha S
Articles: 172