<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: sanket</title>
    <description>The latest articles on DEV Community by sanket (@sanketh_sh).</description>
    <link>https://dev.to/sanketh_sh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1213666%2Fd0f01c4f-a9d1-4ccd-a62d-92eca5cb743c.jpg</url>
      <title>DEV Community: sanket</title>
      <link>https://dev.to/sanketh_sh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sanketh_sh"/>
    <language>en</language>
    <item>
      <title>Mongodb aggregation pipeline with examples</title>
      <dc:creator>sanket</dc:creator>
      <pubDate>Sun, 21 Jan 2024 11:35:49 +0000</pubDate>
      <link>https://dev.to/sanketh_sh/mongodb-aggregation-pipeline-with-examples-183n</link>
      <guid>https://dev.to/sanketh_sh/mongodb-aggregation-pipeline-with-examples-183n</guid>
      <description>&lt;h3&gt;
  
  
  Tools Of Trade
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.mongodb.com/docs/manual/installation/" rel="noopener noreferrer"&gt;MongoDB&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.mongodb.com/products/tools/compass" rel="noopener noreferrer"&gt;Mongo Compass&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am assuming you have MongoDB installed on your system or you are using Mongo Atlas. &lt;br&gt;
You can my use my &lt;a href="https://github.com/indahud/dot_files/blob/main/docker/mongo_compose.yml" rel="noopener noreferrer"&gt;docker file&lt;/a&gt; for quick setup.&lt;br&gt;&lt;br&gt;
I am using MongoDB Compass to write aggregation pipelines. Compass is graphical tool from MongoDB. You are free to use whatever you like. &lt;br&gt;
Compass has some very nice features like exporting pipeline to your preferred programming language, import pipeline, saving pipeline for later usage.&lt;/p&gt;
&lt;h3&gt;
  
  
  Basics
&lt;/h3&gt;

&lt;p&gt;If you are familiar with JavaScript then aggregation pipeline is array of objects. Where each object is stage. &lt;br&gt;
You can think of it as conveyor belt where each stage performs some operation on data and passes its output to next stage. Few examples would be $match, $lookup, $unwind, $project etc.&lt;/p&gt;
&lt;h3&gt;
  
  
  Schema
&lt;/h3&gt;

&lt;p&gt;Before we start writing writing aggregation pipelines, I want to show you fields inside different collections. &lt;br&gt;
I have 2 collections in my &lt;b&gt;fairbnb&lt;/b&gt; database. You can get database data from &lt;a href="https://github.com/indahud/blog_data/tree/main/MongoDB" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;listing collection schema&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvtwb3axqdqigo2huy5f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvtwb3axqdqigo2huy5f.png" alt="listing schema" width="800" height="615"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;profile collection schema&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwsh351x1ba7ls592bqk7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwsh351x1ba7ls592bqk7.png" alt="profile schema" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Examples 🚀🚀
&lt;/h3&gt;


&lt;h3&gt;
  
  
  Simple match :
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;$match&lt;/b&gt;: 
match stage is used to filter out documents based on specific condition/condtions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here we are trying to match field &lt;code&gt;profileID&lt;/code&gt;. It will return matching profileID documents from collection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;
  &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$match&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
      profileID:
        &lt;span class="s2"&gt;"a74ffc48-4534-4b9c-980f-b0d57b96cf8e"&lt;/span&gt;,
    &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If your only goal is to filter out the matching documents then &lt;code&gt;find()&lt;/code&gt; method can be used instead.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;find({ profileID: "a74ffc48-4534-4b9c-980f-b0d57b96cf8e" })&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Match with $and, $or operators :
&lt;/h3&gt;

&lt;p&gt;Now consider you have little more complex situation than this. Where you have multiple conditions, based on that you have to filter the data. We can use different operators to achieve this.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;$and:&lt;/b&gt; It is same as logical AND operator in many programming languages. All true expressions will evaluate to true. It takes array with one or more expressions.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;
  &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$match&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;$and&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;
          profileID:
            &lt;span class="s2"&gt;"a74ffc48-4534-4b9c-980f-b0d57b96cf8e"&lt;/span&gt;,
        &lt;span class="o"&gt;}&lt;/span&gt;,
        &lt;span class="o"&gt;{&lt;/span&gt;
          propertyType: &lt;span class="s2"&gt;"Apartment"&lt;/span&gt;,
        &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="o"&gt;]&lt;/span&gt;,
    &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have multiple propertyTypes in profile collection. But we only want to filter out Apartment with certain profileID.&lt;br&gt;
We are using $and inside &lt;code&gt;$match&lt;/code&gt; stage. We are matching &lt;code&gt;profileID&lt;/code&gt; and &lt;code&gt;propertyType&lt;/code&gt; fields in the expression.&lt;/p&gt;

&lt;p&gt;It will only return documents if it matches both profileID and propertyType provided by us.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;$or: &lt;/b&gt; It is similar to logical OR operator. Any one true expression will evaluate to true.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;
  &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$match&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;$or&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;
          propertyType: &lt;span class="s2"&gt;"Apartment"&lt;/span&gt;,
        &lt;span class="o"&gt;}&lt;/span&gt;,
        &lt;span class="o"&gt;{&lt;/span&gt;
          price: &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$lt&lt;/span&gt;: 4000,
          &lt;span class="o"&gt;}&lt;/span&gt;,
        &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="o"&gt;]&lt;/span&gt;,
    &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If the propertyType is Apartment or price is less than 4000 then it will return the matching documents.&lt;br&gt;
We are using comparison operator &lt;code&gt;$lt&lt;/code&gt; ( less than ) to filter out documents where price is below 4000.&lt;/p&gt;
&lt;h3&gt;
  
  
  Using $and and $or operators together :
&lt;/h3&gt;

&lt;p&gt;There might be some cases where we might want to use &lt;code&gt;$and&lt;/code&gt; and &lt;code&gt;$or&lt;/code&gt; operators together.&lt;br&gt;
Consider this scenario, we must match a certain profileID, and either propertyType can be &lt;code&gt;Apartment&lt;/code&gt; or listingType can be &lt;code&gt;For Sale&lt;/code&gt;&lt;br&gt;
We are using both &lt;code&gt;$and&lt;/code&gt; and &lt;code&gt;$or&lt;/code&gt; operators inside $match stage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;
  &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$match&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;$and&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;
          profileID:
            &lt;span class="s2"&gt;"a74ffc48-4534-4b9c-980f-b0d57b96cf8e"&lt;/span&gt;,
        &lt;span class="o"&gt;}&lt;/span&gt;,
        &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="nv"&gt;$or&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
            &lt;span class="o"&gt;{&lt;/span&gt;
              propertyType: &lt;span class="s2"&gt;"Apartment"&lt;/span&gt;,
            &lt;span class="o"&gt;}&lt;/span&gt;,
            &lt;span class="o"&gt;{&lt;/span&gt;
              listingType: &lt;span class="s2"&gt;"For Sell"&lt;/span&gt;,
            &lt;span class="o"&gt;}&lt;/span&gt;,
          &lt;span class="o"&gt;]&lt;/span&gt;,
        &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="o"&gt;]&lt;/span&gt;,
    &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="o"&gt;]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;$and operator takes 2 expressions. First is &lt;code&gt;profileID&lt;/code&gt; and second is &lt;code&gt;$or&lt;/code&gt; operator.&lt;br&gt;
$or operator takes 2 expressions &lt;code&gt;propertyType&lt;/code&gt; and &lt;code&gt;listingType&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Lookup
&lt;/h3&gt;

&lt;p&gt;Consider we want to show listing documents. &lt;br&gt;
Along with that we also need to show its owners information like their firstName, lastName, coverImage, profileImage etc.&lt;br&gt;
We will use $lookup stage to get data from different collection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;
  &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$match&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
      profileID:
        &lt;span class="s2"&gt;"a74ffc48-4534-4b9c-980f-b0d57b96cf8e"&lt;/span&gt;,
    &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$lookup&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
      from: &lt;span class="s2"&gt;"profile"&lt;/span&gt;,
      localField: &lt;span class="s2"&gt;"profileID"&lt;/span&gt;,
      foreignField: &lt;span class="s2"&gt;"profileID"&lt;/span&gt;,
      as: &lt;span class="s2"&gt;"profileDetails"&lt;/span&gt;,
    &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$unwind&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
      path: &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$profileDetails&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;,
      preserveNullAndEmptyArrays: &lt;span class="nb"&gt;false&lt;/span&gt;,
    &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$project&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
      _id: 0,
      &lt;span class="s2"&gt;"profileDetails._id"&lt;/span&gt;: 0,
      &lt;span class="s2"&gt;"profileDetails.profileID"&lt;/span&gt;: 0,
    &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;$lookup:&lt;/b&gt; 
Is used to perform a left outer join between two collections.
Like the name suggests &lt;code&gt;$lookup&lt;/code&gt; will look inside different collections. 
It will match the field and add its response as new field inside current document.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;$lookup stage is accepting 4 fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;from:&lt;/b&gt; Collection name we want join.&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;localField:&lt;/b&gt; Field name from the collection we are performing aggregation on.&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;foreignField:&lt;/b&gt; Field name from the collection we are joining (same as local)&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;as:&lt;/b&gt; Name of the new field. It can be of your choice.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;First we are creating profile in &lt;code&gt;profile&lt;/code&gt; collection. Based on that &lt;code&gt;profileID&lt;/code&gt; we are creating the listing.&lt;br&gt;
So we can match the &lt;code&gt;profileID&lt;/code&gt; in profile collection. lookup will return array as its output.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;$unwind:&lt;/b&gt; 
unwind stage will turn array items into its own document. We need to pass arrays path to unpack the array. path will start  with &lt;code&gt;$&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes it is possible that field we are trying to match in different collection doesn't exists. &lt;br&gt;
We have an optional boolean field &lt;code&gt;preserveNullAndEmptyArrays&lt;/code&gt; to keep or remove that document.&lt;br&gt;
If we set &lt;code&gt;preserveNullAndEmptyArrays&lt;/code&gt; to true it will keep the document without specific field. Setting it to false will remove the document from result.&lt;/p&gt;

&lt;p&gt;In our case there will be one item in profileDetails array. profileDetails field will be now object&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;$project:&lt;/b&gt;
The $project stage is used to reshape the document. Fields can be included / excluded from the documents. We are removing few fields that are not required. Fields can be excluded with &lt;b&gt;fieldName: 0&lt;/b&gt; and to only include certain fields &lt;b&gt;fieldName: 1&lt;/b&gt; can be used. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since profileDetails is object we can exclude the fields inside it with dot notation.&lt;br&gt;
You cannot perform inclusion and exclusion together. It needs to be either inclusion or exclusion.&lt;/p&gt;
&lt;h3&gt;
  
  
  Lookup with pipeline :
&lt;/h3&gt;

&lt;p&gt;We can use pipeline inside $lookup stage if you want to match multiple fields or you want to perform more operations in the lookup.&lt;br&gt;
It might not be possible with $localField and $foreignField in lookup.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I'm aware that we can directly match profileID in the listing collection. I am doing it this way for this example.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;
  &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$match&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
      profileID:
        &lt;span class="s2"&gt;"a74ffc48-4534-4b9c-980f-b0d57b96cf8e"&lt;/span&gt;,
    &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$lookup&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
      from: &lt;span class="s2"&gt;"listing"&lt;/span&gt;,
      &lt;span class="nb"&gt;let&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        profileID: &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$profileID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;,
      &lt;span class="o"&gt;}&lt;/span&gt;,
      pipeline: &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="nv"&gt;$match&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$expr&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
              &lt;span class="nv"&gt;$and&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
                &lt;span class="o"&gt;{&lt;/span&gt;
                  &lt;span class="nv"&gt;$eq&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
                    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$profileID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;,
                    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$$&lt;/span&gt;&lt;span class="s2"&gt;profileID"&lt;/span&gt;,
                  &lt;span class="o"&gt;]&lt;/span&gt;,
                &lt;span class="o"&gt;}&lt;/span&gt;,
                &lt;span class="o"&gt;{&lt;/span&gt;
                  &lt;span class="nv"&gt;$eq&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
                    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$propertyType&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;,
                    &lt;span class="s2"&gt;"Apartment"&lt;/span&gt;,
                  &lt;span class="o"&gt;]&lt;/span&gt;,
                &lt;span class="o"&gt;}&lt;/span&gt;,
              &lt;span class="o"&gt;]&lt;/span&gt;,
            &lt;span class="o"&gt;}&lt;/span&gt;,
          &lt;span class="o"&gt;}&lt;/span&gt;,
        &lt;span class="o"&gt;}&lt;/span&gt;,
        &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="nv"&gt;$project&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
            _id: 0,
          &lt;span class="o"&gt;}&lt;/span&gt;,
        &lt;span class="o"&gt;}&lt;/span&gt;,
        &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="nv"&gt;$skip&lt;/span&gt;: 0,
        &lt;span class="o"&gt;}&lt;/span&gt;,
        &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="nv"&gt;$limit&lt;/span&gt;: 1,
        &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="o"&gt;]&lt;/span&gt;,
      as: &lt;span class="s2"&gt;"listings"&lt;/span&gt;,
    &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Different stages are used inside pipeline.&lt;br&gt;
Fields can't be directly accessed inside pipeline. We have to define it as variable with let. That variable can be accessed inside pipeline with &lt;code&gt;$$&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$expr&lt;/code&gt; is requierd because we are referencing profileID from &lt;code&gt;let&lt;/code&gt; inside &lt;code&gt;$match&lt;/code&gt; stage.  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;$skip&lt;/code&gt; stage will remove n documents and &lt;code&gt;$limit&lt;/code&gt; stage will show n documents.&lt;/p&gt;
&lt;h3&gt;
  
  
  Group :
&lt;/h3&gt;

&lt;p&gt;$group stage is used to group document according to specific key / keys and perform operations on it. &lt;code&gt;_id&lt;/code&gt; field is key for that document.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;
  &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$match&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
      profileID:
        &lt;span class="s2"&gt;"a74ffc48-4534-4b9c-980f-b0d57b96cf8e"&lt;/span&gt;,
    &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$group&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
      _id: &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$propertyType&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;,
      count: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$sum&lt;/span&gt;: 1,
      &lt;span class="o"&gt;}&lt;/span&gt;,
    &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will return the count for different &lt;code&gt;propertyType&lt;/code&gt; for the &lt;code&gt;profileID&lt;/code&gt;&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>nosql</category>
      <category>webdev</category>
      <category>database</category>
    </item>
    <item>
      <title>Run Multiple NodeJS microservices with tmux</title>
      <dc:creator>sanket</dc:creator>
      <pubDate>Sun, 19 Nov 2023 15:56:15 +0000</pubDate>
      <link>https://dev.to/sanketh_sh/run-multiple-nodejs-microservices-with-tmux-5f30</link>
      <guid>https://dev.to/sanketh_sh/run-multiple-nodejs-microservices-with-tmux-5f30</guid>
      <description>&lt;p&gt;In this guide I will show you how you can use tmux to run multiple NodeJS microservices with single command.&lt;/p&gt;

&lt;p&gt;You will need tmux for this. Tmux is supported for Linux, MacOS and Windows (WSL). If you want to install it, instructions are &lt;a href="https://github.com/tmux/tmux/wiki/Installing" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is tmux ?
&lt;/h2&gt;

&lt;p&gt;Tmux is terminal multiplexer. It lets you create different windows, panes, sessions for terminal.&lt;br&gt;
Multiple terminal seesions can be created with single terminal window. You can detach/attach sessions pretty easily.&lt;br&gt;
Tmux is highly customizable. You can add your own key bindings, colors and other settings.&lt;/p&gt;
&lt;h2&gt;
  
  
  Little backstory
&lt;/h2&gt;

&lt;p&gt;In my everyday job I need to run multiple ExpressJS microservices for different projects.&lt;/p&gt;

&lt;p&gt;To run microservices I need to do the couple of things everytime:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Going inside Microservice directory.&lt;/li&gt;
&lt;li&gt;Split Window into 3/4 parts to manage it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;I usually manage split windows like this&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;1st split window/pane for running the code / checking the logs&lt;/li&gt;
&lt;li&gt;2nd split window/pane for managing the git submodule&lt;/li&gt;
&lt;li&gt;3rd split window/pane for opening repo in code editor / changing the git branches&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;It takes a lot of time &amp;amp; energy to do this everytime. That's why I created this little bash script for this.&lt;/p&gt;

&lt;p&gt;We are going to use this bash script with tmux to automate our workflow.&lt;br&gt;
Then we will assign this bash script as alias. &lt;br&gt;
It will run different microservices for project with single command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nv"&gt;SESSION_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"PROJECT_X"&lt;/span&gt;

&lt;span class="c"&gt;# Directory Names&lt;/span&gt;
&lt;span class="nv"&gt;DIR_ONE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/some_project/auth_directory"&lt;/span&gt;
&lt;span class="nv"&gt;DIR_TWO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/some_project/profile_directory"&lt;/span&gt;

&lt;span class="c"&gt;# Window Names&lt;/span&gt;
&lt;span class="nv"&gt;WINDOW_ONE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"auth"&lt;/span&gt;
&lt;span class="nv"&gt;WINDOW_TWO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"profile"&lt;/span&gt;

&lt;span class="c"&gt;#Commands&lt;/span&gt;
&lt;span class="nv"&gt;DEV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"npm run dev"&lt;/span&gt; 
&lt;span class="nv"&gt;CL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"clear"&lt;/span&gt;

tmux new-session &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nv"&gt;$SESSION_NAME&lt;/span&gt;

&lt;span class="c"&gt;# Auth microservice Window&lt;/span&gt;
tmux new-window &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="nv"&gt;$SESSION_NAME&lt;/span&gt;:1 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nv"&gt;$WINDOW_ONE&lt;/span&gt;
tmux split-window &lt;span class="nt"&gt;-h&lt;/span&gt;
tmux split-window &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; 0
tmux send-keys &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="nv"&gt;$SESSION_NAME&lt;/span&gt;:1.0 &lt;span class="s2"&gt;"cd &lt;/span&gt;&lt;span class="nv"&gt;$DIR_ONE&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; &lt;/span&gt;&lt;span class="nv"&gt;$CL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; C-m
tmux send-keys &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="nv"&gt;$SESSION_NAME&lt;/span&gt;:1.1 &lt;span class="s2"&gt;"cd &lt;/span&gt;&lt;span class="nv"&gt;$DIR_ONE&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; &lt;/span&gt;&lt;span class="nv"&gt;$CL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; C-m
tmux send-keys &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="nv"&gt;$SESSION_NAME&lt;/span&gt;:1.2 &lt;span class="s2"&gt;"cd &lt;/span&gt;&lt;span class="nv"&gt;$DIR_ONE&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; &lt;/span&gt;&lt;span class="nv"&gt;$CL&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; &lt;/span&gt;&lt;span class="nv"&gt;$DEV&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; C-m

&lt;span class="c"&gt;# Profile microservice Window&lt;/span&gt;
tmux new-window &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="nv"&gt;$SESSION_NAME&lt;/span&gt;:2 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nv"&gt;$WINDOW_TWO&lt;/span&gt;
tmux split-window &lt;span class="nt"&gt;-h&lt;/span&gt;
tmux split-window &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; 0
tmux send-keys &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="nv"&gt;$SESSION_NAME&lt;/span&gt;:2.0 &lt;span class="s2"&gt;"cd &lt;/span&gt;&lt;span class="nv"&gt;$DIR_TWO&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; &lt;/span&gt;&lt;span class="nv"&gt;$CL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; C-m
tmux send-keys &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="nv"&gt;$SESSION_NAME&lt;/span&gt;:2.1 &lt;span class="s2"&gt;"cd &lt;/span&gt;&lt;span class="nv"&gt;$DIR_TWO&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; &lt;/span&gt;&lt;span class="nv"&gt;$CL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; C-m
tmux send-keys &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="nv"&gt;$SESSION_NAME&lt;/span&gt;:2.2 &lt;span class="s2"&gt;"cd &lt;/span&gt;&lt;span class="nv"&gt;$DIR_TWO&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; &lt;/span&gt;&lt;span class="nv"&gt;$CL&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; &lt;/span&gt;&lt;span class="nv"&gt;$DEV&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; C-m

tmux &lt;span class="nt"&gt;-u&lt;/span&gt; attach &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="nv"&gt;$SESSION_NAME&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How it is works?
&lt;/h2&gt;

&lt;p&gt;I have defined session name, directory paths and window names in bash script.&lt;br&gt;
It will create two windows with 3 panes in each window. After that it will run &lt;code&gt;npm run dev&lt;/code&gt; in one pane.&lt;br&gt;
I created 3 panes here but you can add as many as you want.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to create Alias ?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Check which shell you are using.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Run this command &lt;code&gt;echo $0&lt;/code&gt; to check your shell. It could be bash/zsh. For zsh you need to create alias in &lt;code&gt;.zshrc&lt;/code&gt; file. For bash create alias in &lt;code&gt;.bashrc&lt;/code&gt; file&lt;/p&gt;

&lt;p&gt;Now we need to tell &lt;code&gt;.zshrc/.bashrc&lt;/code&gt; alias that my script exists in this directory.&lt;br&gt;
Lets consider your bash script resides in &lt;code&gt;$HOME/Scripts&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Create alias like this in &lt;code&gt;.zshrc/.bashrc&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    &lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;project_x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/Scripts/tmux.sh"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Dont forget to change the bash file permission.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    &lt;span class="nb"&gt;chmod&lt;/span&gt; +x tmux.sh  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Refersh environment variables
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    &lt;span class="nb"&gt;source&lt;/span&gt; .zshrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final result
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4jhfeapyj1vagf3vjqg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4jhfeapyj1vagf3vjqg.png" alt="tmux" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>automation</category>
      <category>bash</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
