TypeScript Express tutorial #6. Basic data processing with MongoDB aggregation

175 阅读1分钟

MongoDB aggregation

The MongoDB database contains a mechanism called the MongoDB aggregation framework. It is working with the concepts of data processing pipelines. Documents enter a multi-stage pipeline that can transform them and output the aggregated result.

Since there might be multiple stages, we pass an array to the aggregate function. Every element of that array is an object that has a property naming one of the possible stages that you can use. For example:

const arrayOfJohns = await this.user.aggregate(
  [
    {
      $match: {
        name: 'John',
      },
    },
  ],
);

Using $match works similarly to the find function.

The output of a stage is later passed to the next stage in the array if there are any.

$group

// src/controller/report/report.controller.ts
import express from 'express';
import Controller from '../../interfaces/controller.interface';
import userModel from '../../models/users/user.model';
 
class ReportController implements Controller {
  public path = '/report';
  public router = express.Router();
  private user = userModel;
 
  constructor() {
    this.initializeRoutes();
  }
 
  private initializeRoutes() {
    this.router.get(`${this.path}`, this.generateReport);
  }
 
  private generateReport = async (request: express.Request, response: express.Response, next: express.NextFunction) => {
    const usersByCountries = await this.user.aggregate(
      [
        {
          $group: {
            _id: {
              country: '$address.country',
            },
          },
        },
      ]
    );
    response.send({
      usersByCountries
    });
  }
 
}
 
export default ReportController;

``

```ts
// src/server.ts

const app = new App(
  [
    new PostsController(),
    new AuthenticationController(),
    new ReportController(),  
  ],
);
 
app.listen();

image.png

Combining multiple stages

//src/controller/report/report.controller.ts

import express from "express";
import Controller from "../../interfaces/controller.interface";
import userModel from "../../models/users/user.model";

class ReportController implements Controller {
	public path = "/report";
	public router = express.Router();
	private userModel = userModel;

	constructor() {
		this.initializeRoutes();
	}

	private initializeRoutes() {
		this.router.get(`${this.path}`, this.generateReport);
	}

	private generateReport = async (
		request: express.Request,
		response: express.Response,
		next: express.NextFunction
	) => {
		const usersByCountries = await this.userModel.aggregate([
			{
				$match: {
					"address.country": {
						$exists: true,
					},
				},
			},
			{
				$group: {
					_id: {
						country: "$address.country",
					},
					count: {
						$sum: 1,
					},
					users: {
						$push: {
							name: "$firstName",
							_id: "$_id",
						},
					},
				},
			},
		]);
		response.send({
			usersByCountries,
		});
	};
}

export default ReportController;

image.png

$lookup

ref: source