Mongo Aggregation Framework: A powerful feature
Tags: developer, mernstack, mongodb
Published: 2023-08-30 18:08:29

---
title: Mongo Aggregation Framework: A powerful feature
published: true
date: 2022-03-03 20:39:38 UTC
tags: developer,mernstack,mongo,mongodb
canonical_url: 
---

Most of the tabular databases like Oracle, MySQL, Postgre, etc., give us some tools like joins to get data from multiple tables or the ability to make operations with the data retrieved creating simple or complex SQL statements. On my normal day in the product component that I work, I make complex SQL statements using PL/SQL to build operations to achieve an expected result. Recently, the company began migrating the component to a document-based database and we chose MongoDB. With this election, one of the most popular questions that I asked was: **How can I make operations when retrieving data from the database as I did with the tabular databases?**

After reading a lot and taking some [Mongo University Courses](https://university.mongodb.com/courses/M121/about) I realized something about the MongoDB framework. This is a piece of the MongoDB universe that provides a lot of components and functionalities to make anything that we want with the data. In this paper, I will talk about **_how this framework works and I will introduce you to some of these functionalities that MongoDB gives us._**

### How does it work?

Recently a coworker and I were developing an app to track our finances from the emails sent by the banks; each email contains information about a transaction like payments, withdrawals, transfers, etc.

This information is stored in the mongo database and contains some information like the account, amount, location, and other properties of the transaction. The idea was to accept or reject a transaction and get some statistics of the accepted ones like percentage of the transaction by category, percentage of the transaction by card type (credit or debit card), or expenses vs incomes.

To get some of those statistics, we needed to make some groups and manipulate some data. I was lost at the beginning since I only knew the common things about Mongo like the CRUD operations and the projections, but after some research and courses are taken, the Aggregation Framework became the hero of the day. Let me show you some of the tools that we can use with this framework.

![](https://cdn-images-1.medium.com/max/628/1*gigAdu7ipwvVkNaDvtM3jw.png)
_Image retrieved from https://www.codeproject.com/KB/database/1149682/image001.png_

The Aggregation Framework provides multiple functionalities like _$project, $match, $lookup, $sort, $limit, etc.;_ Tools that we will call for now stages of our pipeline.

The **pipeline** has a simple definition, which is a _collection of stages_ that the database will execute to transform our data.

A **stage** is a functionality that we use to manipulate our data and get the expected result.

Here is something important to remember: the database will execute the stages in the same order that we write them and some stages have restrictions to get a position in the pipeline since we need to use a stage first and then use another one.

We can use this framework like so:

> db.collection.aggregate([stage1, stage2, stage3 ])

We are telling the MongoDB database “Hey, with the data of this **collection** make the next transformation in this order and give me the result”.

#### So, let’s make some comparisons with a tabular database:

Imagine that we have a site to track the expenses of a user, and in the database schema, we separate the payment information from the user data in the data model, like this:

![](https://cdn-images-1.medium.com/max/607/1*Q2i_eUxVJUkdgcVIY1nnzg.png)
_User-Payments diagram_

Now imagine you need to get the payments for a user.

With a Tabular database like Oracle you will need to make an SQL statement like this one:

{% gist https://gist.github.com/AndresMorelos/f2455f02b2951b89303bf1fdcbebadfb %}

In the Oracle database, we will need to use the join functionality to get the data from the payments table using the relationship of the user identification.

But with MongoDB we need to use the aggregation framework and write a pipeline like this:

{% gist https://gist.github.com/AndresMorelos/ff8eeeb6d17a6528846440a425e671da %}

In this pipeline we are using two stages:

**$match:** This stage allows us to make some validations on the data and returns the information that matches them; like the _where_ statement in a tabular database, or a find operation in our MongoDB database.

**$lookup:** This stage allows us to look at data from different collections using a field of the present documents as the relationship identifier, returning to us an array of the documents that match the local and foreign Fields criteria.

#### What happens if the database returns too many users and I want to put a limit?

This is simple to do. Let’s do the comparison from a tabular database with the MongoDB database:

Tabular Database (Oracle):

{% gist https://gist.github.com/AndresMorelos/0eab79a5642a429110004a38acf9e7ef %}

MongoDB pipeline:

{% gist https://gist.github.com/AndresMorelos/967d023e31640264333a1aca7eedd5ba %}

In this pipeline, we introduce the **$limit** stage. This stage does the same as the limit of a tabular database, retrieving the first 5 documents (in MongoDB case) or rows (in a tabular database case).

#### But, what happens if I want to retrieve some data of the payments like the value and the location?

Let’s make the comparison again.

In the tabular database (Oracle):

{% gist https://gist.github.com/AndresMorelos/f81c78564c8963597caf606722aed5fc %}

In this case for the tabular database is simple, I just select the value and location column on the payments table.

In the MongoDB database:

{% gist https://gist.github.com/AndresMorelos/ad46b58332abaaae71d198dd052acf0a %}

In this pipeline, we use the **_$project_** stage, this stage permits us to manipulate the data retrieved like show/hide some specific fields, or make operations using other stages, like the **_$map_** stage used to retrieve only the value and location of the payments.

The **$project** stage is important because we can set binary values to show or hide a field. By default only the _\_id_ and the fields that are entries of the JSON arg are returned; If we need to delete the _\_id_ we need to indicate it this way:

```
{

   _id: 0,
   name: 1,    
   payments:{        
       $map: {          
          input: "$payments",          
          as: "payment",          
          in: {            
                value: '$$payment.value',            
                location: '$$payment.location'          
          }        
       }    
   }

}
```

Returning the following:

![](https://cdn-images-1.medium.com/max/1024/1*uOA5lSvA-hPetvWpixrMPg.png)
_Project output without the _id field_

In contrast, if we do not specify it:

![](https://cdn-images-1.medium.com/max/1024/1*lKuvtY4hNtKQo5hiXB1gVg.png)
_Project output returning the _id field_

### **Conclusions**

The MongoDB aggregation framework gives use powerful functionalities like:

1. Manipulation of our data with simple stages.
2. Multiple powerful stages to do with our data most of the things that we need in a project. [Read more about the stages](https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/).
3. It is supported by all of the drivers provided by the MongoDB team.
4. It allows us to deal with the data like we do with tabular databases in a simple and readable way.

### Recommendations

If this framework got your attention, I would like to recommend you take the [MongoDB M121](https://university.mongodb.com/courses/M121/about) course and read the [aggregation framework](https://docs.mongodb.com/manual/aggregation/) documentation. Don’t forget to follow the [Condor Labs Engineering](https://medium.com/condorlabs-engineering) Medium page to get in touch with the latest papers.

* * *