Filter MongoDB Array Elements

Introduction

Unlike some databases, MongoDB documents sometimes contain fields that have values as arrays. Sometimes a document that contains specific information inside these arrays needs to be checked. This tutorial will explain how to filter MongoDB array elements to extract and project only the necessary data, and not the entire array.

Prerequisites

  • MongoDB must be properly installed and configured on the local system to filter MongoDB array elements.

Creating Sample Dataset

This section will explain how to create a sample dataset that will consist of a collection named icafe and two documents. Begin by executing the following query in the Mongo shell:

db.icafe.insert([
{
  _id : 1001,
  name : "Black Wolf Cafe",
  business_code : "bwc03",
  ratings : [
    {
      name : "james cole",
      star : 5,
      review : "very affordable price"
    },
    {
      name : "richard cole",
      star : 5,
      review : "smooth gaming experience"
    },
    {
      name : "gina cole",
      star : 5,
      review : "superb sounds"
    }
  ],
  location : [
      {
          country : "Korea",
          address : {
              city : "Seoul",
              street : "Mapo-gu"
          }
      }
  ]
},
{
  _id : 1002,
  name : "Curiosity Internet Cafe 1",
  business_code : "bwc04",
  ratings : [
    {
      name : "bikong nam",
      star : 5,
      review : "very clean environment"
    },
    {
      name : "dred jordan",
      star : 5,
      review : "fast internet connection"
    },
    {
      name : "yeshua",
      star : 5,
      review : "smooth gaming pc"
    }
  ],
  location : [
      {
          country : "Philippines",
          address : {
              city : "Manila",
              street : "Bocobo"
          }
      }
  ]
}
]);

The output should resemble the following:

BulkWriteResult({
        "writeErrors" : [ ],
        "writeConcernErrors" : [ ],
        "nInserted" : 2,
        "nUpserted" : 0,
        "nMatched" : 0,
        "nModified" : 0,
        "nRemoved" : 0,
        "upserted" : [ ]
})

Using $elemMatch

This $elemMatch method covered in this section will explain how to match documents that have an array field that contains at least one of the element that matches all of defined criteria of a given query.

Here is the basic form of the $elemMatch operator:

<field> : { $elemMatch : { <firstCondition>, <secondCondition2>, … } }

Using $elemMatch with find() method

Execute the following query in the Mongo shell to use the $elemMatch operator with the find() function:

db.icafe.find(
  { location : { $elemMatch : { country : "Korea", "address.city" : "Seoul" } } }
).pretty();

The results should resemble the following:

{
        "_id" : 1001,
        "name" : "Black Wolf Cafe",
        "business_code" : "bwc03",
        "ratings" : [
                {
                        "name" : "james cole",
                        "star" : 5,
                        "review" : "very affordable price"
                },
                {
                        "name" : "richard cole",
                        "star" : 5,
                        "review" : "smooth gaming experience"
                },
                {
                        "name" : "gina cole",
                        "star" : 5,
                        "review" : "superb sounds"
                }
        ],
        "location" : [
                {
                        "country" : "Korea",
                        "address" : {
                                "city" : "Seoul",
                                "street" : "Mapo-gu"
                        }
                }
        ]
}
>

Using $filter

Sometimes extracting or projecting all of the fields in the target document isn’t required, but only those records that match a defined criteria. Here the $filter operator can be used to refine and obtain the desired results.

The $filter operator has three variables:

  1. cond – This is the condition or requirement.
  2. as – This is the reference name.
  3. input – This is the target array.

Execute the following code to effect the $filter operator:

db.icafe.aggregate([
{
   "$match" : {
       "location" : {
          "$elemMatch" : {
             "$and" : [
                { "country" : "Philippines" },
                { "address.city" : "Manila" }
             ]
          }
       },
   }
},
{
   "$project" : {
       "business_code" : 1, "name" : 1,
       "location" : {
          "$filter" : {
             "input" : "$location",
             "as" : "location",
             "cond" : {
                "$and" : [
                   { "$eq" : [ "$$location.country", "Philippines" ] },
                   { "$eq" : [ "$$location.address.city", "Manila" ] }
                ]
             }
          }
       }
   }
}
]).pretty();

Note that the above code is designed to filter the projected results by excluding the ratings field in the document. Its output should resemble the following:

{
        "_id" : 1002,
        "name" : "Curiosity Internet Cafe 1",
        "business_code" : "bwc04",
        "location" : [
                {
                        "country" : "Philippines",
                        "address" : {
                                "city" : "Manila",
                                "street" : "Bocobo"
                        }
                }
        ]
}

Now note that the above results were successfully filtered as defined by the $match and $filter operator.

Conclusion

This tutorial explained how to filter MongoDB array elements to extract and project only the needed data contained in an array. The tutorial explained how to create a sample dataset and then use the $elemMatch and $elemMatch with the find() method to match documents that have an array field that contains at least one of the specified elements. The article also explained how to use $filter with the three variables to pull up only those records that match a defined criteria. Remember that all three of the variables must be used in the $filter operator to obtain the desired results.

Pilot the ObjectRocket Platform Free!

Try Fully-Managed CockroachDB, Elasticsearch, MongoDB, PostgreSQL (Beta) or Redis.

Get Started

Keep in the know!

Subscribe to our emails and we’ll let you know what’s going on at ObjectRocket. We hate spam and make it easy to unsubscribe.