Filter nested array MongoDB C#

Today in this article, we will see how to MongoDB-Query deeply nested array containing a specific value.

Today in this article, we will cover below aspects,

We will cover below a few specific scenarios like dealing with [] array type elements,

  • Get documents based on matching nested array size i.e where array size is greater or less than of given specified size.
  • Find the array that contains specific values only.
  • Specify conditions for array elements.

Sample schema as below,

Filter nested array MongoDB C#

In the above example, we have two nested arrays Example Books [] and Category [].

MongoDB – Find document from Nested array element

Command

Nested 3 array pattern,

{ <array-field1>.<array-field2>.<array-field3>.<Field-Name>: {<value> }

The below example shows an array filter where we get the list of documents where the value of a nested array element i.e category [] is equal to the value specified.

{'Books.category.key': 'test2-1'}

Example

Filter nested array MongoDB C#

MongoDB – Find documents by nested array length

Command

{ <array-field1>.<array-field2: {$size :<size-specified> }

Example

The below example shows an array filter where we get the list of documents based on array size i.e category [] size is equal to the size specified.

{'Books.category': {$size:2}}
Filter nested array MongoDB C#

MongoDB – Find a document with a nested array by specifying multiple conditions

Example

MongoDB query array with fields that contains a given string,

{'Books.category.key': {$regex: '-'}}

Above query returns records where array element “Key” attribute has a value that matches or contains “-“.

You are asked to filter on this column. If this field would have carried dictionaries, then the query for applying the filter would have been comparatively easier. However, this is not the case.

To achieve this, you need to unwind this column and apply the match operator.

The $unwind Operator

By using the $unwind operator on the target field, it will separate the elements in the array into its own documents and then we match for the element we want.

The below code will apply a filter on a collection ‘ProductMaster’ to get all the documents where ‘categories’ has one or more specified elements mentioned in $in operator.

The query below:

SQL

db.getCollection('ProductMaster')
  .aggregate( {$unwind: '$categories'}, {$match: {"categories": {$in: ['Beauty']}}} );

Points of Interest

This morning, I got into a wierd kind of a scenario where I had to apply the filter on an array inside another array. The filter on a string or numeric columns are very straight forward and we have been doing the same from the day we started programming. But this was a unique scenario I came across and the search was on. Every article I was going through was only talking about how to apply a filter on a dictionary carrying column. In a dictionary, you have some relaxation because you can grab a key in order to get its value. In an array of arrays, you don't have any keys. I applied the query meant for dictionaries and started playing around with it. And somehow, I managed to do so and got the desired results.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Filter nested array MongoDB C#

Written By

Pankaj Jha

Filter nested array MongoDB C#
 India

This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

To set filtering conditions, use $filter and $cond in MongoDB aggregate(). The $filter selects a subset of an array to return based on the specified condition. Let us create a collection with documents −

> db.demo725.insertOne(
...    {
...
...       "details": {
...
...          "userMessages": [
...             {
...                "Messages": [
...                   { "Message": "Hello" },
...                   { "Message": "How" },
...                   { "Message": "are" }
...                ]
...
...             },
...             {
...                "Messages": [
...                   { "Message": "Good" },
...                   { "Message": "Bye" }
...
...                ]
...             },
...             {
...                "Messages": [
...                   { "Message": "Hello" },
...                   { "Message": "Bye" }
...
...                ]
...
...             }
...          ]
...       }
...    }
... );
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5eab16cd43417811278f5893")
}

Display all documents from a collection with the help of find() method −

> db.demo725.find();

This will produce the following output −

{ "_id" : ObjectId("5eab16cd43417811278f5893"), "details" : { "userMessages" : [ { "Messages" : [ { "Message" : "Hello" }, { "Message" : "How" }, { "Message" : "are" } ] }, { "Messages" : [ { "Message" : "Good" }, { "Message" : "Bye" } ] }, { "Messages" : [ { "Message" : "Hello" }, { "Message" : "Bye" } ] } ] } }

Following is the query to set filtering conditions for nested array −

> db.demo725.aggregate([
...    {
...       $addFields: {
...          "details.userMessages": {
...             $filter: {
...                input: "$details.userMessages",
...                as: "out",
...                cond: {
...                   $anyElementTrue: {
...                      $map: {
...                         input: "$$out.Messages",
...                         in: { $gte: [ { $indexOfBytes: [ "$$this.Message", "Hello" ] }, 0 ] }
...                      }
...                   }
...                }
...             }
...          }
...       }
...    }
... ]).pretty()

This will produce the following output −

{
   "_id" : ObjectId("5eab16cd43417811278f5893"),
   "details" : {
      "userMessages" : [
         {
            "Messages" : [
               {
                  "Message" : "Hello"
               },
               {
                  "Message" : "How"
               },
               {
                  "Message" : "are"
               }
            ]
         },
         {
            "Messages" : [
               {
                  "Message" : "Hello"
               },
               {
                  "Message" : "Bye"
               }
            ]
         }
      ]
   }
}

Filter nested array MongoDB C#


Filter nested array MongoDB C#

How to filter an array in MongoDB?

Filter MongoDB Array Element Using $Filter Operator This operator uses three variables: input – This represents the array that we want to extract. cond – This represents the set of conditions that must be met. as – This optional field contains a name for the variable that represent each element of the input array.

How do I search inside an array in MongoDB?

To query if the array field contains at least one element with the specified value, use the filter { <field>: <value> } where <value> is the element value. To specify conditions on the elements in the array field, use query operators in the query filter document: { <array field>: { <operator1>: <value1>, ... } }

How to query nested fields in MongoDB?

In MongoDB, you can access the fields of nested/embedded documents of the collection using dot notation and when you are using dot notation, then the field and the nested field must be inside the quotation marks. Document: three documents that contain the details of the students in the form of field-value pairs.

What is $filter in MongoDB?

Definition. $filter. Selects a subset of an array to return based on the specified condition. Returns an array with only those elements that match the condition. The returned elements are in the original order.