<?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: Mạnh Đạt</title>
    <description>The latest articles on DEV Community by Mạnh Đạt (@datmt).</description>
    <link>https://dev.to/datmt</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%2F175464%2F781d44b7-43d2-488f-84c9-fde52cf3b6ec.png</url>
      <title>DEV Community: Mạnh Đạt</title>
      <link>https://dev.to/datmt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/datmt"/>
    <language>en</language>
    <item>
      <title>I Built An Animation Tool With Angular!</title>
      <dc:creator>Mạnh Đạt</dc:creator>
      <pubDate>Fri, 09 Sep 2022 09:18:44 +0000</pubDate>
      <link>https://dev.to/datmt/i-built-an-animation-tool-with-angular-19pd</link>
      <guid>https://dev.to/datmt/i-built-an-animation-tool-with-angular-19pd</guid>
      <description>&lt;h2&gt;
  
  
  Motivation to create
&lt;/h2&gt;

&lt;p&gt;Recently, I blogged more than I used to. Most of the posts are tutorials. &lt;/p&gt;

&lt;p&gt;I tried to add images, diagrams when possible. However, I think videos work best when describing procedures.&lt;/p&gt;

&lt;p&gt;Diagrams are cool but it would be even more awesome if objects on diagrams can move :D.&lt;/p&gt;

&lt;p&gt;So I created a tool to do just that: Helps me create videos to explain processes quickly.&lt;/p&gt;

&lt;p&gt;You may say: Hey, there are many great video tool out there that you can learn in a few hours and they can do more than what you need!&lt;/p&gt;

&lt;p&gt;Yes, I know. Great tools (even free) are out there but being able to create something outweigh all reasons.&lt;/p&gt;

&lt;p&gt;I ended up spending mostly a week creating the first "usable" version.&lt;/p&gt;

&lt;h2&gt;
  
  
  The app
&lt;/h2&gt;

&lt;p&gt;So here it is:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Feerbmxobmthmrnora1be.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Feerbmxobmthmrnora1be.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vanim.datmt.com/" rel="noopener noreferrer"&gt;https://vanim.datmt.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I created a video showing how to use the app here:&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=RE6RbT69VS0" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=RE6RbT69VS0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can go there and start playing with the tool. You can create some shapes, use images to create moving diagrams...&lt;/p&gt;

&lt;p&gt;Here is one example I created to explain the concept of CountDownLatch in Java&lt;/p&gt;


  


&lt;h2&gt;
  
  
  Future of the app
&lt;/h2&gt;

&lt;p&gt;I have some ideas in mind. The main purpose is to make creating videos even easier. I know the app is primitive now but I can now create some nice animation for my blog :).&lt;/p&gt;

&lt;p&gt;Your suggestions are highly appreciated!&lt;/p&gt;

&lt;h2&gt;
  
  
  Special thanks
&lt;/h2&gt;

&lt;p&gt;This app is not possible without the following projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fabricjs &lt;a href="http://fabricjs.com/:" rel="noopener noreferrer"&gt;http://fabricjs.com/:&lt;/a&gt; It is the engine that run the app. Thanks!&lt;/li&gt;
&lt;li&gt;Jenkins: Thanks to this awesome projects, I can literally push new changes online in just a single click.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for your attention. Have a great weekend and hope you have fun creating new things!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Java Concurrency: Threads communication tutorial</title>
      <dc:creator>Mạnh Đạt</dc:creator>
      <pubDate>Wed, 07 Sep 2022 05:08:42 +0000</pubDate>
      <link>https://dev.to/datmt/java-concurrency-06-threads-communication-45fi</link>
      <guid>https://dev.to/datmt/java-concurrency-06-threads-communication-45fi</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Java provides mechanisms for threads to communicate with each other when working on common resources. This post gives you a concrete example of threads communication.&lt;/p&gt;

&lt;h2&gt;
  
  
  Threads communication example
&lt;/h2&gt;

&lt;p&gt;Let's consider this scenario. Alice is a computer programmer who also has a love for buying new shiny things (phones, laptops, gadgets). She has a list of things to buy. She works at a company called MonkeyTypes Inc. Her paycheck is $1,000 monthly.&lt;br&gt;
Imagine she currently has this wishlist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A new Macbook: $3000&lt;/li&gt;
&lt;li&gt;A new mechanical keyboard: $400,&lt;/li&gt;
&lt;li&gt;A new phone: $500,&lt;/li&gt;
&lt;li&gt;A new shiny gadget: $500&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;She wants to have all of them in no particular order.&lt;br&gt;
Her current balance is $0. What she wants is when she gets her monthly salary, she would spend the money in her balance to buy any of those things.&lt;br&gt;
Let's see how we can convert this scenario to demonstrate thread communication.&lt;/p&gt;
&lt;h2&gt;
  
  
  Code implementation
&lt;/h2&gt;

&lt;p&gt;For this scenario, let's create two Runnable tasks: One to simulate Alice paycheck and other to simulate her purchase.&lt;br&gt;
We also need a class to represent her bank account.&lt;br&gt;
Let's create the bank account class first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BankAccount&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;


    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Lock&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ReentrantLock&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Condition&lt;/span&gt; &lt;span class="n"&gt;paycheckArrivedCondition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newCondition&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;getPaid&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lock&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Getting paid "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;paycheckArrivedCondition&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;signalAll&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unlock&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="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;purpose&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lock&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;paycheckArrivedCondition&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;await&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Withdraw "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" to "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;purpose&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"new balance -&amp;gt; "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unlock&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;As you can see, this class has one field: &lt;code&gt;balance&lt;/code&gt; to hold the current balance. Also, there are two methods to deposit and withdraw money to and from the balance.&lt;br&gt;
The most interesting details here are the lock and the condition. I created a static lock and a static condition at the beginning of the class. The lock, as you may know, helps synchronize access to the balance. The condition, on the other hand, helps make communication between threads possible.&lt;/p&gt;
&lt;h3&gt;
  
  
  The withdraw() method
&lt;/h3&gt;

&lt;p&gt;At the beginning of the &lt;code&gt;withdraw&lt;/code&gt; method, the &lt;code&gt;lock&lt;/code&gt; method on the ReentrantLock instance is called. This ensures that only the thread that has the lock can execute the code in this function.&lt;br&gt;
Next, the try/catch/finally blocks make sure the lock is released at the end.&lt;br&gt;
The while loop checks if the balance has enough money, if not, the &lt;code&gt;await&lt;/code&gt; function is called on the condition instance.** This call releases the lock.**&lt;/p&gt;
&lt;h3&gt;
  
  
  The deposit() method
&lt;/h3&gt;

&lt;p&gt;Similar to the &lt;code&gt;withdraw()&lt;/code&gt; method, threads need to acquire the lock to execute code here. One interesting thing about this method is the call to the method &lt;code&gt;signalAll&lt;/code&gt;on the condition instance. This call is the meat of thread communication. This wakes up all the waiting threads and the check for balance &amp;gt; amount starts again.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Runnable class to deposit money
&lt;/h2&gt;

&lt;p&gt;Now the BankAccount class is available, let's create a runnable class to deposit money to a BankAccount instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PayEmployee&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Runnable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;BankAccount&lt;/span&gt; &lt;span class="n"&gt;bankAccount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;PayEmployee&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BankAccount&lt;/span&gt; &lt;span class="n"&gt;employeeBankAccount&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bankAccount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;employeeBankAccount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;bankAccount&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPaid&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&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;h2&gt;
  
  
  The Runnable class to withdraw money
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BuyThings&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Runnable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;BankAccount&lt;/span&gt; &lt;span class="n"&gt;bankAccount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;purpose&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;BuyThings&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BankAccount&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;purpose&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bankAccount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;purpose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;purpose&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Plan to "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;purpose&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" with "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;bankAccount&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withdraw&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;purpose&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;h2&gt;
  
  
  Alice buys things in action
&lt;/h2&gt;

&lt;p&gt;Now let's implement the code where Alice submits her wishlist.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;BankAccount&lt;/span&gt; &lt;span class="n"&gt;myAccount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BankAccount&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;executors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Executors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newFixedThreadPool&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;executors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BuyThings&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myAccount&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"buy new macbook pro"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3_000&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;executors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BuyThings&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myAccount&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"buy new phone"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;executors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BuyThings&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myAccount&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"buy new keyboard"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;executors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BuyThings&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myAccount&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"buy new gadgets"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;cycle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cycle&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
               &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;

            &lt;span class="n"&gt;executors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PayEmployee&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myAccount&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1_000&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
            &lt;span class="n"&gt;cycle&lt;/span&gt;&lt;span class="o"&gt;--;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;executors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shutdown&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;From line 4 to line 7, all her purchases are submitted.&lt;br&gt;
From line 9 to line 19, I simulate her payment. Let's say her contract with the company has only 6 months left. Let's run the program and see the output:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gA0n2otr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/09/image-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gA0n2otr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/09/image-2.png" alt="Thread communication in action" width="880" height="613"&gt;&lt;/a&gt;&lt;br&gt;
As you can see, after getting paid the first $1000, Alice buys a phone and then a new keyboard ... However, this order is not consistent. The next run may produce different order. One certain thing is a MacBook always gets purchased last because only after the next-to-final payment, Alice have enough money to afford this.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--heMS2P0a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/09/image-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--heMS2P0a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/09/image-3.png" alt="Different purchasing order" width="880" height="623"&gt;&lt;/a&gt;&lt;br&gt;
You may ask, what if Alice only has 4 payment cycles left instead of 6? That means she never has enough money for a MacBook. In such a case, the program will run forever because the buy Macbook thread keeps waiting for the condition to meet. (so sad :( )&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this post, I have introduced you to the concept of thread communication in Java using Lock and condition. A thread can acquire the lock, and check if the condition is met. If the condition is not met, a call to &lt;code&gt;await&lt;/code&gt; on the condition instance releases the lock for other threads. A thread can notify all other threads by using &lt;code&gt;signalAll&lt;/code&gt; (or &lt;code&gt;signal&lt;/code&gt; to notify a random thread).&lt;br&gt;
The code for this post is available here on &lt;a href="https://github.com/datmt/java-core-tutorial/blob/main/src/com/datmt/java_core/concurrency/ThreadCommunication.java" rel="noreferrer noopener nofollow"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This post is a part of the &lt;a href="https://datmt.com/series/java-concurrency/"&gt;Java concurrency tutorial series&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>beginners</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>MongoDB Aggregation Framework Cheat Sheet</title>
      <dc:creator>Mạnh Đạt</dc:creator>
      <pubDate>Tue, 02 Aug 2022 10:14:18 +0000</pubDate>
      <link>https://dev.to/datmt/mongodb-aggregation-framework-cheat-sheet-3ock</link>
      <guid>https://dev.to/datmt/mongodb-aggregation-framework-cheat-sheet-3ock</guid>
      <description>&lt;h2&gt;
  
  
  Importing sample data
&lt;/h2&gt;

&lt;p&gt;This post is a quick introduction to the MongoDB Aggregation Framework. It's a part of a mini-series called &lt;a href="https://datmt.com/series/mongodb-cheat-sheets/" rel="noreferrer noopener"&gt;Mongo DB Cheatsheets&lt;/a&gt;&lt;br&gt;
To follow the tutorial, you need to import the following data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"first_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Larry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"last_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Freeman"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"networth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;340&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"investments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Oil Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1990&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bank Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1995&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bank Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1997&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Publishing Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1995&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;130&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Beer Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2005&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Energy Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2005&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;55&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"first_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bill"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"last_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Freeman"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"networth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"investments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Oil Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1992&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Oil Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1995&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bank Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1995&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bank Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2005&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"first_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Jerry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"last_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Whackman"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"networth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;190&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"investments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Publishing Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1990&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;130&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Beer Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1990&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Energy Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2005&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"first_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mary"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"last_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Whackman"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"networth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;280&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"investments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Oil Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1997&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bank Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2005&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Auto Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2008&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;125&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"first_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Kate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"last_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Whackman"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"networth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"investments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Logistics Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2017&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bank Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2005&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Auto Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2008&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This sample is a list of 5 rich people from two families. The data contains their net worth and their investments over the years.&lt;br&gt;
To import the data, open the MongoDB shell, select the database (starter) and do the import like this:&lt;/p&gt;



&lt;p&gt;Now you are ready for some aggregations!&lt;/p&gt;
&lt;h2&gt;
  
  
  MongoDB Aggregation Overview
&lt;/h2&gt;

&lt;p&gt;You can think of aggregation as a pipeline where your data goes through a number of steps. The output of one step is the input of the next step.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SWPjYN62--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/07/image-63-1024x370.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SWPjYN62--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/07/image-63-1024x370.png" alt="MongoDB aggregation visualization" width="880" height="318"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  MongoDB Aggregation Quick example
&lt;/h2&gt;

&lt;p&gt;From the list of rich people above, say, you want to get the people from the Whackman family, order the results by their net worth, and only display their name and net worth, ignoring other fields.&lt;br&gt;
Then you can issue this aggregation query to achieve the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.rich.aggregate&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; last_name: &lt;span class="s2"&gt;"Whackman"&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;$sort&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt; networth: 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="nv"&gt;$project&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt; _id: 0, first_name: 1, last_name: 1, networth: 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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Gkb2EqdR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Gkb2EqdR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image.png" alt="A simple MongoDB aggregation operation" width="876" height="426"&gt;&lt;/a&gt;&lt;br&gt;
As you can see, this aggregation has three stages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;$match: filter only matched documents. In the example, I filtered rich people who have a source as self-made&lt;/li&gt;
&lt;li&gt;$sort: sort by field. (1 for ascending, -1 for descending)&lt;/li&gt;
&lt;li&gt;$project: select fields to display (1 for showing, 0 for hiding)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The positions of the stages in the aggregation array determine the running order. That means in the example above, &lt;code&gt;$match&lt;/code&gt; runs first, then &lt;code&gt;$set&lt;/code&gt; and finally &lt;code&gt;$project&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using $match for Filtering
&lt;/h2&gt;

&lt;p&gt;You can use $match as you can with &lt;code&gt;find&lt;/code&gt;. This stage allows you to filter data to a smaller set.&lt;br&gt;
In the list above, you can use $match to filter people from one family only. For example, let's get only people from the Freeman family:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.rich.aggregate&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; last_name: &lt;span class="s2"&gt;"Freeman"&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;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---i-81x9f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---i-81x9f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-4.png" alt="Using a simple $match in MongoDB" width="876" height="821"&gt;&lt;/a&gt;&lt;br&gt;
You can also use $match to do more complex filters like so:&lt;br&gt;
Filter documents that made investments in years later than 2006. Notice that this filter still outputs the full documents with investments &lt;strong&gt;before &lt;/strong&gt;2006 (if any). The only requirement is that document has at least one investment after 2006.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.rich.aggregate&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="s2"&gt;"investments.year"&lt;/span&gt; : &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;$gt&lt;/span&gt;: 2006&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;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c4aFc-qe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c4aFc-qe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-5.png" alt="Using $match to filter nested properties" width="876" height="821"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using $project
&lt;/h2&gt;

&lt;p&gt;You use $project to modify fields, create new fields, and show and hide fields.&lt;br&gt;
Here are some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Display people with their first name, last name and net worth only:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$project&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;networth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UPzREtpF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UPzREtpF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-10.png" alt="Use $project to show/hide fields" width="866" height="689"&gt;&lt;/a&gt;&lt;br&gt;
In this example, for fields I want to show, I set the value to 1. I need to hide _id field explicitly. Other fields are hidden if there are no settings for them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding a new calculated field to the document&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's say there is a 10% tax applied to these rich people's net worth and you want to display that field in the document. $project would handle that easily:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt; 
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$project&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;networth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;calculated_tax&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;$divide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$networth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hzhfD7Jb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-11.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hzhfD7Jb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-11.png" alt="Using $project to calculate new fields" width="866" height="827"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using $unwind
&lt;/h2&gt;

&lt;p&gt;I cannot put a better definition than the official of $unwind so here it is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Deconstructs an array field from the input documents to output a document for each element.&lt;/p&gt;
&lt;cite&gt;https://www.mongodb.com/docs/manual/reference/operator/aggregation/unwind/&lt;/cite&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, you have this document:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Jane&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hobbies&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Reading&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Swimming&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running $unwind on this object, you will have two objects&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Jane&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hobbies&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Reading&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Jane&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hobbies&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Swimming&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lNN5Q0wG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lNN5Q0wG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-1.png" alt="MongoDB $unwind example" width="876" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's say the requirement is to show only investments in the Publishing Industry made by all of the people.&lt;br&gt;
From the requirements, I'm going to write an aggregation pipeline with two stages: $unwind and $match:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$unwind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$investments&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;investments.name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Publishing Industry&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1-bP2eJ1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1-bP2eJ1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-2.png" alt="MongoDB Unwind in action" width="876" height="511"&gt;&lt;/a&gt;&lt;br&gt;
In this example, in the first steps, I used $unwind to deconstruct the &lt;code&gt;investments&lt;/code&gt; array. As a result, for each investment, I have one document. If I only run the $unwind stage, here is the output:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--06mlOEM8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--06mlOEM8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-3.png" alt="MongoDB unwind stage" width="876" height="821"&gt;&lt;/a&gt;&lt;br&gt;
As you can see, for one person (Larry Freeman for example), instead of one document, now he has multiple documents, each containing one of his investments.&lt;br&gt;
The $match stage filters out all the investments from industries that aren't "Publishing Industry". Thus, I got the result as expected.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using $group
&lt;/h2&gt;

&lt;p&gt;$group is one of the most powerful operators in the aggregation framework. As the name suggests, you use $group when you want to group documents that have common traits into one document.&lt;/p&gt;

&lt;p&gt;Here are some important things you want to know about $group:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need to define a "group key", which is a common trait. This "group key" can be a field, a group of fields, or an expression&lt;/li&gt;
&lt;li&gt;You define the group key using _id&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's try an example with $group. Let's say I want to get the unique family names in the collections. From the beginning of this post, I already know that there are only two families: Freeman and Whackman&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$last_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n_tuK5no--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n_tuK5no--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-6.png" alt="Simple usage of $group stage" width="866" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Using accumulators in $group
&lt;/h3&gt;

&lt;p&gt;Using accumulators helps you get some nice results with minimal code.&lt;br&gt;
For example, you want to calculate the total net worth of each family. This is what you need to execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$last_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;total_networth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$networth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}}}&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3LdjCGbu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3LdjCGbu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-7.png" alt="Using sum aggregator in $group" width="866" height="500"&gt;&lt;/a&gt;&lt;br&gt;
You can also use another function, $avg to calculate the average net worth of each family:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$last_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;total_networth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$avg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$networth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}}}&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HHHn-QwD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HHHn-QwD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-8.png" alt="Calculate average net worth with $avg accumulator" width="866" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using $sample to extract a portion of a large dataset
&lt;/h2&gt;

&lt;p&gt;There are times you have to work with large datasets. That means the document count is in the millions range. In such cases, you may want to work with a portion of that collection, says 1,000.&lt;br&gt;
The &lt;code&gt;$sample&lt;/code&gt; operator helps you do that.&lt;br&gt;
For example, the dataset in this post has 5 documents and I only want to work with 2, this is what I do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$sample&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--urXo8HRh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--urXo8HRh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-9.png" alt="Using $sample to work with a subset of the dataset" width="866" height="689"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical MongoDB aggregation
&lt;/h2&gt;

&lt;p&gt;In this section, we are going to solve some questions using aggregations.&lt;/p&gt;

&lt;h3&gt;
  
  
  List the unique name of the industries
&lt;/h3&gt;

&lt;p&gt;For this question, we are going to use $unwind and $group&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$unwind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$investments&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$investments.name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qJnB2cOd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qJnB2cOd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-12.png" alt="" width="866" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Which family invests most in the Oil industry?
&lt;/h3&gt;

&lt;p&gt;For this question, we will do these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use $unwind to deconstruct the investments&lt;/li&gt;
&lt;li&gt;Use $match to filter out other industries.&lt;/li&gt;
&lt;li&gt;Use $group to group the family name and $sum to calculate the total amount
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$unwind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$investments&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;investments.name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Oil Industry&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$last_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;total_investment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;$sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$investments.value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uQ804L9f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-13.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uQ804L9f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-13.png" alt="Using aggregation to calculate total investments in Oil Industry by family" width="880" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rank people by the total value of their investments
&lt;/h3&gt;

&lt;p&gt;In this task, we need to calculate the sum of each person's investments and then rank the value descendingly.&lt;br&gt;
There are many ways to do this but this is one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, $unwind the investments array&lt;/li&gt;
&lt;li&gt;Then $group by first name and last name, and use $sum to calculate the total investments' value&lt;/li&gt;
&lt;li&gt;Use $sort to order the total value descendingly
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;$unwind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$investments&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$first_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$last_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;total_investment_value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$investments.value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$sort&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;total_investment_value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EAdoz4qG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-15-1024x428.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EAdoz4qG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-15-1024x428.png" alt="Calculate total investments value for all people and order the total descendingly" width="880" height="368"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Calculate the total net worth, and average net worth of each family and rank them by average net worth
&lt;/h3&gt;

&lt;p&gt;At this point, you probably know what to do.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use $group and $sum, $avg to calculate the requested values&lt;/li&gt;
&lt;li&gt;Use $sort to rank the average net worth value
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$last_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;$sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$networth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="na"&gt;average&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;$avg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$networth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}}},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$sort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;average&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
  &lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rWgxl2M6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-16-1024x428.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rWgxl2M6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-16-1024x428.png" alt="Calculate sum and average networth by family" width="880" height="368"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Rank the top 3 investments by value.
&lt;/h3&gt;

&lt;p&gt;This is yet another task we need to use $unwind. Here are the steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use $unwind to deconstruct the investment array&lt;/li&gt;
&lt;li&gt;Use $sort to sort the investments by values&lt;/li&gt;
&lt;li&gt;Use $limit to get only the top 3 items
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.rich.aggregate([
  { $unwind: "$investments" },
  { $sort: { "investments.value": -1 } },
  { $limit: 3}
  ])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F1AsubA1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-17-1024x531.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F1AsubA1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-17-1024x531.png" alt="Find the top 3 investments" width="880" height="456"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Which year has the most investment amount?
&lt;/h3&gt;

&lt;p&gt;To solve this question, we need to use $unwind, $group, $sort, and $limit&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$unwind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$investments&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$investments.year&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;$sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$investments.value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$sort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;amount&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jM3gGdbc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-18-1024x531.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jM3gGdbc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-18-1024x531.png" alt="Find the year with the most investment value" width="880" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Count the number of people who have a total investment value greater than 50 in each family
&lt;/h3&gt;

&lt;p&gt;To complete this request, we need to do quite many things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use $unwind to deconstruct the investment array&lt;/li&gt;
&lt;li&gt;Use $group by _id and $sum to calculate the total investment value of each person. In this step, we also use the accumulator $first to extract the family name and store it in a field called family_name&lt;/li&gt;
&lt;li&gt;Use $match to filter out people with less than 50 investment values&lt;/li&gt;
&lt;li&gt;Use $group on last name and $sum to count the number of the remaining people.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$unwind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$investments&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$_id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;family_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;$first&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$last_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;invest_value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$investments.value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;invest_value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$gt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$family_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;people_count&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;$sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}}}&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Kjfq0zu2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-19-1024x531.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Kjfq0zu2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://datmt.com/wp-content/uploads/2022/08/image-19-1024x531.png" alt="Count the number of people per family that have investment value more than 50" width="880" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this post, we have learned some of the most common usages of the MongoDB aggregation framework. This post is by no mean a complete reference. You need to refer to the &lt;a href="https://www.mongodb.com/docs/" rel="noreferrer noopener nofollow"&gt;official documentation&lt;/a&gt; for a complete list.&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>MongoDB Basic CRUD Cheat Sheet</title>
      <dc:creator>Mạnh Đạt</dc:creator>
      <pubDate>Thu, 28 Jul 2022 18:32:22 +0000</pubDate>
      <link>https://dev.to/datmt/mongodb-basic-crud-cheat-sheet-2nfd</link>
      <guid>https://dev.to/datmt/mongodb-basic-crud-cheat-sheet-2nfd</guid>
      <description>&lt;p&gt;If you have been doing software development for some time, you'd probably know what CRUD is. CRUD stands for CREATE-READ-UPDATE-DELETE. Those are the day to day task we do on databases, regardless of their types.&lt;br&gt;
Let's get started by using a new database. As you may remember from the previous post, there is no "create" command in MongoDB. We simply use the use command. I'm going to call my new database starter&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;use starter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-43.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-43.png" alt="Create new database in MongoDB"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Collection CRUD
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create Collections
&lt;/h3&gt;

&lt;p&gt;Before inserting documents, you need to create collections. You can create a collection by:&lt;br&gt;
null&lt;br&gt;
Let me demonstrate&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.createCollection&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"create_explicitly"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
db.create_implicitly.insert&lt;span class="o"&gt;({})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On line 1, I called the createCollection explicitly and gave that function a name.&lt;br&gt;
On line 2, I assumed the collection named create_implicitly exist and inserted an empty document.&lt;br&gt;
In both cases, the collections were created successfully&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-44.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-44.png" alt="Two ways to create a MongoDB Collection"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Rename collection
&lt;/h3&gt;

&lt;p&gt;To rename a collection, simply call renameCollection on the collection you want to rename&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;# Create a wrong name collection&lt;/span&gt;
db.createCollection&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"wrong_name"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Rename the collection&lt;/span&gt;
db.wrong_name.renameCollection&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"correct_name"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-46.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-46.png" alt="Rename a collection"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Drop collection
&lt;/h3&gt;

&lt;p&gt;To remove a collection (and all documents inside), simply call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.create_implicitly.drop&lt;span class="o"&gt;()&lt;/span&gt;
db.create_explicitly.drop&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-45.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-45.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Document CRUD
&lt;/h2&gt;

&lt;p&gt;In this section, we are going to learn how to do basic CRUD on documents&lt;/p&gt;

&lt;h3&gt;
  
  
  Create document
&lt;/h3&gt;

&lt;p&gt;You have three functions to create documents in MongoDB. They are insert, insertOne and insertMany&lt;/p&gt;

&lt;h4&gt;
  
  
  Using insert
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.dogs.insert&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Bingo"&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
db.dogs.insert&lt;span class="o"&gt;([{&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Pie"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt; : &lt;span class="s2"&gt;"Borg"&lt;/span&gt;&lt;span class="o"&gt;}])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-47.png" alt="Using insert to create documents in MongoDB"&gt;&lt;/a&gt;&lt;br&gt;
As you can see, you can insert one document or many documents using insert.&lt;/p&gt;
&lt;h4&gt;
  
  
  Using insertOne
&lt;/h4&gt;

&lt;p&gt;As the name suggest, insertOne inserts only one document. Thus, it accepts only objects, not array&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.dogs.insertOne&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Biscuit"&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-48.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-48.png" alt="Using insertOne in MongoDB"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Using insertMany
&lt;/h4&gt;

&lt;p&gt;Similar to insert, you can insert multiple documents using insertMany. This function accepts only array, not object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.dogs.insertMany&lt;span class="o"&gt;([{&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Steven"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Jessica"&lt;/span&gt;&lt;span class="o"&gt;}])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-49.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-49.png" alt="Using insertMany in MongoDB"&gt;&lt;/a&gt;&lt;br&gt;
You may wonder, what are the differences between insert and insertOne and insertMany?&lt;br&gt;
Take a look at the screenshots, return types are different.&lt;/p&gt;
&lt;h3&gt;
  
  
  Read Documents
&lt;/h3&gt;

&lt;p&gt;Now we have some documents, let's try getting them&lt;/p&gt;
&lt;h4&gt;
  
  
  Using find
&lt;/h4&gt;

&lt;p&gt;The most common way to retrieve documents in MongoDB is using find&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.dogs.find&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-50.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-50.png"&gt;&lt;/a&gt;&lt;br&gt;
You can pass a filter object to the find function to get exactly what you need.&lt;br&gt;
For example, finding the dog with name "Bingo" looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.dogs.find&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt; : &lt;span class="s2"&gt;"Bingo"&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-51.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-51.png"&gt;&lt;/a&gt;&lt;br&gt;
You are not limited to exact matching. For example, you can use regex to search for documents.&lt;br&gt;
Let's find all the dogs with names begin with "B"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.dogs.find&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt; : &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$regex&lt;/span&gt;: /B.&lt;span class="k"&gt;*&lt;/span&gt;/i&lt;span class="o"&gt;}})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-52.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-52.png" alt="Use find with regex"&gt;&lt;/a&gt;&lt;br&gt;
There are many other powerful queries you can do with find. However, that's a topic for another post. We only do basic CRUD here.&lt;/p&gt;
&lt;h3&gt;
  
  
  Update documents
&lt;/h3&gt;

&lt;p&gt;In the update command, you need to specify the query to get the matched documents and the operation you want to do on those documents.&lt;/p&gt;
&lt;h4&gt;
  
  
  Update one document
&lt;/h4&gt;

&lt;p&gt;You can update a document by using its ObjectId.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.dogs.update&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;{&lt;/span&gt;_id:  ObjectId&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"62e2533531ed3d24b2e3e0df"&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;$set&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt; age: 5 &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;In this example, I knew that the dog named "Bingo" has that specific ObjectId. So, I passed that in the query object and operate the $set operation on its age field. I queried the dog "Bingo" again, I could see the age field is set to 5.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-54.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-54.png" alt="Update a document by ID"&gt;&lt;/a&gt;&lt;br&gt;
Update a document by ID&lt;br&gt;
In case your query returns multiple documents and you only want to update the first one, use updateOne or update&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.dogs.updateOne&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;{&lt;/span&gt;name:  &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$regex&lt;/span&gt;: /B.&lt;span class="k"&gt;*&lt;/span&gt;/i &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;$set&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt; age: 8 &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;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-58.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-58.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Update multiple documents
&lt;/h4&gt;

&lt;p&gt;You can use the update command to execute update on multiple documents, not just one&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.dogs.update&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;{&lt;/span&gt;name:  &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$regex&lt;/span&gt;: /B.&lt;span class="k"&gt;*&lt;/span&gt;/i &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;$set&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt; age: 6 &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;{&lt;/span&gt;multi: &lt;span class="nb"&gt;true&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;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-55.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-55.png" alt="Update multiple documents "&gt;&lt;/a&gt;&lt;br&gt;
As you can see, I needed to set {multi: true} to update multiple documents. By default, the update function only updates one record.&lt;br&gt;
If I try to find all the dogs with name starts with B, I can see they all have age set to 6:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-56.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-56.png" alt="Viewing result after update"&gt;&lt;/a&gt;&lt;br&gt;
You can also use updateMany to update multiple documents without passing {mulitple: true}&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.dogs.updateMany&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;{&lt;/span&gt;name:  &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$regex&lt;/span&gt;: /B.&lt;span class="k"&gt;*&lt;/span&gt;/i &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;$set&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt; age: 7 &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;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-57.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-57.png" alt="Update multiple documents using updateMany"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Delete documents
&lt;/h3&gt;

&lt;p&gt;Similar to update, you also need to write a query to find the matched documents and call delete on them.&lt;/p&gt;

&lt;h4&gt;
  
  
  Delete one document
&lt;/h4&gt;

&lt;p&gt;Use deleteOne to delete one document from the list of matches. That means, even if you have more than one document, there is only one will be deleted:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.dogs.deleteOne&lt;span class="o"&gt;({&lt;/span&gt;name: &lt;span class="s2"&gt;"Bingo"&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-60.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-60.png" alt="Delete one document"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Delete all matched documents
&lt;/h4&gt;

&lt;p&gt;If you want to delete all matches documents, use deleteMany&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;db.dogs.deleteMany&lt;span class="o"&gt;({&lt;/span&gt;name: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$regex&lt;/span&gt;: /B.&lt;span class="k"&gt;*&lt;/span&gt;/i&lt;span class="o"&gt;}})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-61.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-61.png" alt="Delete many documents"&gt;&lt;/a&gt;&lt;br&gt;
In the example above, I first find the dogs that have names start with B. As you can see, there were two result.&lt;br&gt;
After issuing the deleteMany query, none was found.&lt;/p&gt;

&lt;h4&gt;
  
  
  Delete all documents
&lt;/h4&gt;

&lt;p&gt;If you want to delete all documents in a collection, simply call deleteMany passing and empty filter object. This is similar to the command TRUNCATE in SQL databases.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-62.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-62.png" alt="Delete all documents in MongoDB"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this post, I have listed some of the most common CRUD commands in MongoDB. The list is far from comprehensive but it is a good start for people who have just learned this NoSQL database.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>mongodb</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Setup MongoDB Test Environment With Docker</title>
      <dc:creator>Mạnh Đạt</dc:creator>
      <pubDate>Thu, 28 Jul 2022 18:30:47 +0000</pubDate>
      <link>https://dev.to/datmt/setup-mongodb-test-environment-with-docker-17m2</link>
      <guid>https://dev.to/datmt/setup-mongodb-test-environment-with-docker-17m2</guid>
      <description>&lt;p&gt;This tutorial helps you quickly setup a MongoDB instance so you can start learning this topic right away.&lt;br&gt;
We are going to use MongoDB 5 in this series. I haven't tested with other versions so if you are from the past or the future, make sure you use the correct version as in this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running MongoDB with docker
&lt;/h2&gt;

&lt;p&gt;If you have Docker installed, running MongoDB is really easy:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

docker run &lt;span class="nt"&gt;-dit&lt;/span&gt; &lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;always &lt;span class="nt"&gt;-p&lt;/span&gt; 27017:27017 mongo:5.0


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

&lt;/div&gt;

&lt;p&gt;Here, I mapped the port 27017 of MongoDB to the port 27017 of the host. If your host doesn't have the port 27017 available, change that number to a different number.&lt;br&gt;
You only need to do the port mapping if you want to connect to the instance using clients such as MongoDB Compass. If you use the shell (as I'm going to), you just need to run this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

docker run &lt;span class="nt"&gt;-dit&lt;/span&gt; &lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;always mongo:5.0


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

&lt;/div&gt;

&lt;p&gt;I run the container in detach mode and make it always restart for convenient.&lt;br&gt;
Let's check if the instance is running:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

docker ps


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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-35-1024x567.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-35-1024x567.png" alt="Running mongoDB with docker"&gt;&lt;/a&gt;&lt;br&gt;
As you can see, I have already setup one instance and it's available there.&lt;br&gt;
You should be able to see your instance as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connect to the MongoDB Shell inside Docker container
&lt;/h2&gt;

&lt;p&gt;As mentioned above, I'm not going to use a client but the MongoDB shell inside the docker container. From the docker ps command's output, I know that the container id is: bbc5....&lt;br&gt;
So, I can execute inside the container by issuing the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; bbc5a637b0e6 bash


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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-36.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-36.png"&gt;&lt;/a&gt;&lt;br&gt;
Inside the container, type mongo and you can access the mongo shell&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-38.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-38.png" alt="The mongo shell"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  MongoDB Hierachy
&lt;/h2&gt;

&lt;p&gt;In MongoDB, at the top level, you have databases. Inside databases, there are collections. Inside collections, you have documents.&lt;br&gt;
Documents are JSON objects that contain keys and values.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-41.png" alt="MongoDB hierachy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic MongoDB commands cheat sheet
&lt;/h2&gt;

&lt;p&gt;To clear the screen type:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

cls


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

&lt;/div&gt;

&lt;p&gt;And hit enter&lt;br&gt;
To show available databases, type:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

show dbs


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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-39.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-39.png" alt="Show mongo databases"&gt;&lt;/a&gt;&lt;br&gt;
To use a particular database, type:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

use &amp;lt;dbname&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-40.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-40.png" alt="Use a database"&gt;&lt;/a&gt;&lt;br&gt;
One important note here: There is no create database command in MongoDB. You can "create" one by simply using the use command.&lt;br&gt;
To show all documents in a collection, type:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

db.&amp;lt;collectionName&amp;gt;.find&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="c"&gt;# For example:&lt;/span&gt;
db.friends.find&lt;span class="o"&gt;()&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-42.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-42.png" alt="Listing documents in MongoDB collections"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this post, I've shown you how to setup MongoDB and do some basic queries. We are going to learn more about MongoDB in the next articles.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>mongodb</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Spring Cloud Config Server Complete Guide</title>
      <dc:creator>Mạnh Đạt</dc:creator>
      <pubDate>Fri, 22 Jul 2022 12:13:31 +0000</pubDate>
      <link>https://dev.to/datmt/spring-cloud-config-server-complete-guide-4in5</link>
      <guid>https://dev.to/datmt/spring-cloud-config-server-complete-guide-4in5</guid>
      <description>&lt;h2&gt;
  
  
  Overview of Spring Cloud Config Server
&lt;/h2&gt;

&lt;p&gt;Spring Cloud config server is a REST application that is built on top of Spring Boot. The main purpose of a config server is to store the configurations for all services in an application (think microservices). Thus, each service doesn't need to store its configurations. They just need to point to the config server to get their configurations.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-7-1024x680.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-7-1024x680.png" alt="Spring Cloud Config Server overview"&gt;&lt;/a&gt;&lt;br&gt;
Spring Cloud Config Server can work with various technologies to deliver the configurations in a secure way such as HashiCorp Vault, Git, or file system (less secure, not suitable for most production environments).&lt;br&gt;
Let's get started with an example.&lt;/p&gt;
&lt;h2&gt;
  
  
  Spring Cloud Config Server Quick Start
&lt;/h2&gt;

&lt;p&gt;Let's say we are building a microservice application for a restaurant chain. One of the services is called cook service. All it does is report the number of cooks available in the whole chain. For simplicity's sake, we are going to build a Spring Boot application with just one controller like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.datmt.springcloud.cookservice.controller&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.beans.factory.annotation.Value&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.cloud.context.config.annotation.RefreshScope&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.GetMapping&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.RequestMapping&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.RestController&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CookController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;


    &lt;span class="nd"&gt;@Value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"${cook.count}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;cookCount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;cook&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Cook count: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;cookCount&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;As you can see, this service gets the number of cooks in an application properties variable called cook.count. Normally, we would set such properties in the service application.properties file. However, today, we will get it from somewhere else: Spring Cloud config server!&lt;br&gt;
There are many ways to define configurations for services in the config server (which we are going to discover later). In this section, we will read the configuration from the file system.&lt;br&gt;
Let's take a look at configuration of our Spring cloud config server:&lt;br&gt;
Let's pay attention to the last 2 lines of this config file. In line 3, we specified the active profile for configuration file scan, which is native. That means spring cloud configuration server will scan the file system. Line 4 specifies the exact location to search. The classpath refers to resources directory in our project:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fspring-cloud-config-server-file-path.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fspring-cloud-config-server-file-path.png" alt="Spring cloud configuration server native file system "&gt;&lt;/a&gt;&lt;br&gt;
In the cook-service*.properties files, there are one setting that has different values for different environment:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-10.png"&gt;&lt;/a&gt;&lt;br&gt;
In the config folder, there are three files for the cook service. Why are these files named like this? By convention, configurations files for services have this format: servicename-env.yaml or servicename-env.properties.&lt;br&gt;
That means the service name here must match the name in the cook service application.properties&lt;br&gt;
The configuration file of the cook service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;server.port=9977
spring.application.name=cook-service
spring.profiles.active=dev
spring.cloud.config.uri=http://localhost:9988
spring.config.import=optional:configserver:http://localhost:9988
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, on line 2, we named the service as cook-service. Line 3 specify the active profile, which is dev. That means the configurations for cook service will be read from the file config/cook-service-dev.properties on the config server. In case that file is not available, the content of the file config/cook-service.properties will be used.&lt;br&gt;
Let's start the config server and see what we have:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-8.png" alt="Spring cloud config server default profile"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-9.png" alt="Spring cloud config server dev profile"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-11.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-11.png" alt="Spring cloud config server prod profile"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-12.png" alt="Spring cloud config server non-existent profile"&gt;&lt;/a&gt;&lt;br&gt;
As you can see, the configuration URL for dev and prod profiles includes the default configurations. For a nonexistent profile, the default config will be served.&lt;br&gt;
Now, let's start the cook service to see if it can get the right configuration. Remember, the active profile is dev so we would expect to see the number 190:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-13.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-13.png" alt="Get configuration from config server in other services"&gt;&lt;/a&gt;&lt;br&gt;
If we change the active profile to prod&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;server.port=9977
spring.application.name=cook-service
spring.profiles.active=prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and reload the cook service, the output will change:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-14.png"&gt;&lt;/a&gt;&lt;br&gt;
As you can see, we have successfully gotten the configuration for the cook service from the config server.&lt;br&gt;
In the next section, we will try to reload the configuration when there are updates on the config server without reloading the cook service.&lt;/p&gt;
&lt;h2&gt;
  
  
  Refreshing configuration with Actuator
&lt;/h2&gt;

&lt;p&gt;If there are changes in the config server, how can you update the cook service so it will get the correct values without restarting?&lt;br&gt;
Spring Actuator is the answer.&lt;br&gt;
In the pom.xml file, add Spring Actuator as a dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependencies&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-boot-starter-actuator&amp;lt;/artifactId&amp;gt;
        &amp;lt;/dependency&amp;gt;

      &amp;lt;!-- Omit other dependencies --&amp;gt;
    &amp;lt;/dependencies&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the service application.properties file, add the following line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;management.endpoints.web.exposure.include=refresh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the controller, add the annotation @RefreshScrope to the class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.datmt.springcloud.cookservice.controller&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.beans.factory.annotation.Value&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.cloud.context.config.annotation.RefreshScope&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.GetMapping&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.RequestMapping&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.RestController&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@RefreshScope&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CookController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;


    &lt;span class="nd"&gt;@Value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"${cook.count}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;cookCount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;cook&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Cook count: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;cookCount&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;By adding these configurations, we can now call the cook service at /actuator/refresh to request a refresh.&lt;br&gt;
For example, for the current running environment (prod), we change the value 4000 to 5000 and then send the following request:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-15.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-15.png" alt="Sending request to request configuration from config server"&gt;&lt;/a&gt;&lt;br&gt;
As you can see, the service responds back with the config that changed.&lt;br&gt;
If we reload the cook service now, the value should be updated.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-16.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-16.png" alt="Using actuator to refresh config at run time"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Configure Spring Cloud Config Server With Git
&lt;/h2&gt;

&lt;p&gt;Let's find out how you can use git to store your configurations and let the config server pull the data and serve it to other services.&lt;/p&gt;
&lt;h3&gt;
  
  
  Using Public Git
&lt;/h3&gt;

&lt;p&gt;Let's say we have a repository on GitHub storing the config files like this:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-17-1024x243.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-17-1024x243.png"&gt;&lt;/a&gt;&lt;br&gt;
The content of those files is exactly the same as the ones we have on our local machine. Let's configure the config server to use git.&lt;br&gt;
The configuration is quite simple, you only need to make these changes to the application.properties file in the config server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;server.port=9988
spring.application.name=config-server
spring.profiles.active=native, git
spring.cloud.config.server.native.search-locations=classpath:/config
spring.cloud.config.server.git.uri=https://github.com/datmt/quick-samples.git
spring.cloud.config.server.git.search-paths=config-server/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pay attention to lines number 3, 5, and 6. On line 3, we added git as an active profile without removing the native option.&lt;br&gt;
You may wonder, how does the config server choose which profile to use? The answer is the last one on the list.&lt;br&gt;
On line 5, we point to the Git repository.&lt;br&gt;
On line 6, we tell the config server the path to the config files.&lt;br&gt;
Let's restart the config server and see if it can read the config:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-18-1024x566.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-18-1024x566.png" alt="Config server reads configuration from git"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the config server was able to read the configurations from git without problems.&lt;br&gt;
Let's change a value on git and see if the output is updated. Let's say we change the cook.count value from 5000 to 3000:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-19.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-19.png" alt="Changing configuration values on git"&gt;&lt;/a&gt;&lt;br&gt;
Just by reloading the browser, we can see the configuration has changed!&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fconfig-server-using-git-1024x559.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fconfig-server-using-git-1024x559.png"&gt;&lt;/a&gt;&lt;br&gt;
Isn't this awesome? Of course! But who would store sensitive data like configuration in a public git? Let's add some authentication, shall we?&lt;/p&gt;
&lt;h3&gt;
  
  
  Adding Git authentication for security
&lt;/h3&gt;

&lt;p&gt;Let's switch the git repository to a private one. Now, the configuration looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;server.port=9988
spring.application.name=config-server
spring.profiles.active=native, git
spring.cloud.config.server.native.search-locations=classpath:/config
spring.cloud.config.server.git.uri=https://github.com/datmt/Quick-Sample-private.git
spring.cloud.config.server.git.search-paths=config-server/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we launch the config service now and visit the configuration URL of the cook service, we would see an error page:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-20.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-20.png"&gt;&lt;/a&gt;&lt;br&gt;
This is because the config server is unable to read the files from GitHub since the repo is private.&lt;br&gt;
How can we configure it so the config server can read the data? We are going to use GitHub personal access token!&lt;br&gt;
You can follow the guide here to create one: &lt;a href="https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token" rel="noopener noreferrer"&gt;https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token&lt;/a&gt;&lt;br&gt;
After creating the token, we will put the details in the config server application.properties&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;server.port=9988
spring.application.name=config-server
spring.profiles.active=native, git
spring.cloud.config.server.native.search-locations=classpath:/config
spring.cloud.config.server.git.uri=https://github.com/datmt/Quick-Sample-private.git
spring.cloud.config.server.git.search-paths=config-server/config
spring.cloud.config.server.git.username=my&lt;span class="p"&gt;_&lt;/span&gt;temp&lt;span class="p"&gt;_&lt;/span&gt;access&lt;span class="p"&gt;_&lt;/span&gt;token
spring.cloud.config.server.git.password=ghp&lt;span class="p"&gt;_&lt;/span&gt;D6AlGb0f9CY......D5XG0UqzJB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see on lines 7 and 8, both username and password are needed. The password is the access token, obviously. The username is the name of the token.&lt;br&gt;
Now, if we reload the Spring cloud config server, we can see the settings again:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-21-1024x550.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-21-1024x550.png" alt="Configure private git access for spring cloud config server"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Enable Configuration Encryption for Security
&lt;/h2&gt;

&lt;p&gt;Up until now, all the configurations are stored in plaintext. This is not the best practice.&lt;br&gt;
Let's add some security layer by enabling encryption.&lt;br&gt;
Spring cloud config server supports both symmetric and asymmetric encryption. We are going to implement symmetric encryption in this post.&lt;br&gt;
Let's add encryption settings in the config server application.properties file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;server.port=9988
spring.application.name=config-server
spring.profiles.active=native, git
spring.cloud.config.server.native.search-locations=classpath:/config
spring.cloud.config.server.git.uri=https://github.com/datmt/quick-samples.git
spring.cloud.config.server.git.search-paths=config-server/config
encrypt.key=SUPER&lt;span class="p"&gt;_&lt;/span&gt;SECRET&lt;span class="p"&gt;_&lt;/span&gt;ENCRYPT&lt;span class="p"&gt;_&lt;/span&gt;KEY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On line 7, we put the settings for encryption with the encryption key. In production settings, this is a bad practice. You should at least store the encryption key as an environment variable so it is not exposed in the source code.&lt;br&gt;
With these new settings, we can send a POST request to the config server /encrypt to encrypt data. For example, if we want to encrypt the number 5000, the request should be like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: text/plain"&lt;/span&gt; http://localhost:9988/encrypt &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the output:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-22.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-22.png"&gt;&lt;/a&gt;&lt;br&gt;
Now let's put that value to our git:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-23-1024x380.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-23-1024x380.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-24-1024x458.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2022%2F07%2Fimage-24-1024x458.png" alt="Enable encryption on spring cloud configuration server"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this post, we have learned how to use the Spring cloud config server to centralize configurations for all other services. It is a versatile solution that supports multiple mechanisms to store and manage data such as file system, git, HashiCorp Vault, JDBC&lt;/p&gt;

</description>
      <category>java</category>
      <category>cloud</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>[2 days appwrite] Transfer text/Files between devices</title>
      <dc:creator>Mạnh Đạt</dc:creator>
      <pubDate>Wed, 11 May 2022 20:07:56 +0000</pubDate>
      <link>https://dev.to/datmt/2-days-appwrite-transfer-textfiles-between-devices-1pom</link>
      <guid>https://dev.to/datmt/2-days-appwrite-transfer-textfiles-between-devices-1pom</guid>
      <description>&lt;h3&gt;
  
  
  Overview of My Submission
&lt;/h3&gt;

&lt;p&gt;The app lets people share text/image/file between devices.&lt;/p&gt;

&lt;p&gt;This grows from my need as I worked in a quite restricted environment (VPN, blocked sites, apps). &lt;/p&gt;

&lt;p&gt;Every time I need to share some text between PC and mobile, I need to use Skype, which is very buggy.&lt;/p&gt;

&lt;p&gt;So this app let me paste text on any device and get it on others. &lt;/p&gt;

&lt;p&gt;It also works with files. &lt;/p&gt;

&lt;p&gt;Here is the app URL:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://x2.openexl.com/"&gt;https://x2.openexl.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is how the app work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For example,  you want to share a piece of text from your PC to your mobile, you paste that text in the Bury It section:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Il7m1yFO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hchlxw1hcilinqn2ynfh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Il7m1yFO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hchlxw1hcilinqn2ynfh.png" alt="paste text to bury" width="880" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, you click on the button "Bury it". After a few seconds, you will get the code to use it on other devices:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H3gc7CBf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0t4lxtzs04u8kjiyid4j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H3gc7CBf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0t4lxtzs04u8kjiyid4j.png" alt="bury text and get the code" width="880" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On a difference device, you use that code and put into the Dig it section. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d1iJKlLR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/44w6aa22ify5lcquciue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d1iJKlLR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/44w6aa22ify5lcquciue.png" alt="Enter code to dig" width="880" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hit the button and you'll see the text appear:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--paXoQKuY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3d768lp1kn7j6e5q5w6w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--paXoQKuY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3d768lp1kn7j6e5q5w6w.png" alt="text transferred" width="880" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same flow for transferring files. &lt;/p&gt;

&lt;h3&gt;
  
  
  Submission Category:
&lt;/h3&gt;

&lt;p&gt;Web2 Wizards&lt;/p&gt;

&lt;h3&gt;
  
  
  Link to Code
&lt;/h3&gt;

&lt;p&gt;There are two parts of the app. One web app (Angular) and api (written in Spring boot). &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/datmt/File-Bury-APP"&gt;https://github.com/datmt/File-Bury-APP&lt;/a&gt; (Angular)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/datmt/File-Bury-API"&gt;https://github.com/datmt/File-Bury-API&lt;/a&gt; (Spring boot)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Additional Resources / Info
&lt;/h3&gt;

&lt;p&gt;This app is not possible without these projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/appwrite/demo-todo-with-angular"&gt;https://github.com/appwrite/demo-todo-with-angular&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;appwrite&lt;/li&gt;
&lt;li&gt;Spring boot&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>appwritehack</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Fix Permission denied (public key) With Gitlab Windows</title>
      <dc:creator>Mạnh Đạt</dc:creator>
      <pubDate>Fri, 06 May 2022 02:43:37 +0000</pubDate>
      <link>https://dev.to/datmt/fix-permission-denied-public-key-with-gitlab-windows-161b</link>
      <guid>https://dev.to/datmt/fix-permission-denied-public-key-with-gitlab-windows-161b</guid>
      <description>&lt;p&gt;Recently I need to checkout a new repo from a self-hosted Gitlab server. I did the usual thing: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate a pair of ssh keys using &lt;code&gt;ssh-keygen&lt;/code&gt; (since I'm on a new Windows machine). If you already have the ssh keys (try ls in your ~/.ssh and you see &lt;code&gt;id_rsa&lt;/code&gt; and &lt;code&gt;id_rsa.pub&lt;/code&gt;), then you don't need to generate the key pairs again.&lt;/li&gt;
&lt;li&gt;Add it to the SSH key section of Gitlab&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But still, I got the error:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F5589338vwfvs9kvi5q9n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F5589338vwfvs9kvi5q9n.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Normally, it should work, right? Yes, I've done this countless time with GitHub, Gitlab, Bitbucket... and had no issue.&lt;/p&gt;

&lt;p&gt;By the way, the account has 2FA enabled.&lt;/p&gt;

&lt;p&gt;I don't know the reason for this but I have a workaround.&lt;/p&gt;

&lt;h1&gt;
  
  
  Access to Gitlab using personal access token
&lt;/h1&gt;

&lt;p&gt;The workaround is to use Gitlab's personal access token. I haven't tried this on Github (since it works perfectly with SSH key) but I guess it should work too.&lt;/p&gt;

&lt;p&gt;The first step is to generate a personal access token:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fyfsd6b9x5p2hnyu8jfjb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fyfsd6b9x5p2hnyu8jfjb.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, enter the name of the token and check &lt;code&gt;api&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F60qfkkjhyayt0w22ukif.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F60qfkkjhyayt0w22ukif.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then click on Create personal access token and you will get a token to use:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ftdacohahog67mcmrbfbr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ftdacohahog67mcmrbfbr.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, head back to your repository and copy the standard https URL. It should look something like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

https://git.some-server.com/group/repo/repo-name.git


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

&lt;/div&gt;

&lt;p&gt;You need to modify that URL a bit using your newly created token:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

https://&amp;lt;token_name&amp;gt;:&amp;lt;token&amp;gt;@git.some-server.com/group/repo/repo-name.git


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

&lt;/div&gt;

&lt;p&gt;Now, I can use that url to clone the repo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F4rpe694smehf3401f3xb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F4rpe694smehf3401f3xb.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In case you already have the repo, you just need to update the remote url&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

git remote set-url origin https://&amp;lt;token_name&amp;gt;:&amp;lt;token&amp;gt;@git.some-server.com/group/repo/repo-name.git


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

&lt;/div&gt;

&lt;p&gt;Then you can pull, push normally.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;That's it! You can continue working on your repo again. I still don't know why adding ssh didn't work but using the personal access token is an acceptable work around. &lt;/p&gt;

&lt;p&gt;One thing I don't like about this method is any one who can access to your machine can run:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

git remote -v


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

&lt;/div&gt;

&lt;p&gt;And see your access token. That person then can use the credentials to do what you can on your repo.&lt;/p&gt;

&lt;p&gt;So, lock your screen when you are not at your computer :D&lt;/p&gt;




&lt;p&gt;If you enjoy this post, make sure to check my blog out at &lt;a href="https://datmt.com" rel="noopener noreferrer"&gt;https://datmt.com&lt;/a&gt;. I wrote about #programming stuffs there :)&lt;/p&gt;

</description>
      <category>git</category>
      <category>devops</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Using Keycloak to authorize &amp; authenticate Spring Boot application</title>
      <dc:creator>Mạnh Đạt</dc:creator>
      <pubDate>Sun, 21 Nov 2021 10:38:54 +0000</pubDate>
      <link>https://dev.to/datmt/using-keycloak-to-authorize-authenticate-spring-boot-application-4d9</link>
      <guid>https://dev.to/datmt/using-keycloak-to-authorize-authenticate-spring-boot-application-4d9</guid>
      <description>&lt;p&gt;Recently I started an SaaS project. For any project, one of the first problems you need to solve is authentication and authorization. It's 2021 and it's quite foolish to build your own system to log users in and check their role. After a few weeks study available options, I decided to go with Spring Boot &amp;amp; Keycloak.&lt;/p&gt;

&lt;p&gt;If you don't know Keycloak, it's an opensource project that help you quickly setup authentication &amp;amp; authorization for your app. In my case, this is a perfect fit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;App has three roles member, moderator, admin&lt;/li&gt;
&lt;li&gt;API must have endpoints to create user and let user login&lt;/li&gt;
&lt;li&gt;Endpoints authorization could be configure with path prefix (for example /admin...) or by developer specifies the role allowed for each endpoint (using @RolesAllowed)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The code
&lt;/h2&gt;

&lt;p&gt;The project is available here on Github, you can checkout and try it right away:&lt;br&gt;
&lt;a href="https://github.com/datmt/Keycloak-Spring-Boot-Login-Create-User"&gt;https://github.com/datmt/Keycloak-Spring-Boot-Login-Create-User&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Need tutorial?
&lt;/h2&gt;

&lt;p&gt;If you need step by step tutorial, check my post here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://datmt.com/backend/integrate-keycloak-with-spring-boot-step-by-step/"&gt;https://datmt.com/backend/integrate-keycloak-with-spring-boot-step-by-step/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Keycloak is a mature solution for authorization and authentication. It has quite many customization that can fit into various needs. If you can use it in your project, it can save you a great deal of valuable time.&lt;/p&gt;

</description>
      <category>java</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>Create an Electron desktop app version of jwt.io</title>
      <dc:creator>Mạnh Đạt</dc:creator>
      <pubDate>Thu, 01 Jul 2021 01:08:14 +0000</pubDate>
      <link>https://dev.to/datmt/create-an-electron-desktop-app-version-of-jwt-io-36d4</link>
      <guid>https://dev.to/datmt/create-an-electron-desktop-app-version-of-jwt-io-36d4</guid>
      <description>&lt;p&gt;So last night, for some reasons I couldn't access jwt.io to decode a token (the website was loading very slowly) so I thought why didn't I create a desktop app so I don't have to suffer from this wait in the future?&lt;/p&gt;

&lt;p&gt;Well, after a few hours of work, I got exactly (nearly) what I wanted:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qCkbM-dX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h32wgwunuu157kq8dt4x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qCkbM-dX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h32wgwunuu157kq8dt4x.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me show you how I did it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Search for electron vue
&lt;/h2&gt;

&lt;p&gt;I didn't work with electron much but I knew that it's based on Javascript so it's a good chance that somebody has already created a project that have electron bundle with Vue. My guess was right, I found this awsome repo on github:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/SimulatedGREG/electron-vue"&gt;https://github.com/SimulatedGREG/electron-vue&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All credit to the author.&lt;br&gt;
I cloned the repo and opened it in VSCode.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2: Find a jwt decoder
&lt;/h2&gt;

&lt;p&gt;Again, with google, I got this repo from Auth0 that help me decode jwt to get header and body:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/auth0/jwt-decode"&gt;https://github.com/auth0/jwt-decode&lt;/a&gt;&lt;br&gt;
Again, thanks the developers.&lt;/p&gt;

&lt;p&gt;So in my project, I ran&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install jwt-decode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And I got the first working version.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step3: Install codemirror for syntax highlighting
&lt;/h2&gt;

&lt;p&gt;I used this repo:&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/vue-codemirror"&gt;https://www.npmjs.com/package/vue-codemirror&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks the developer :)&lt;/p&gt;

&lt;p&gt;But only get basic function of a code editor functioning. I couldn't get syntax highlighting work yet (Have no idea why, hopefully you guys can give a pointer).&lt;/p&gt;

&lt;p&gt;So, with the help of all the awesome developers of the repos I cloned, I got a working version of a jwt decode in just a few hours.&lt;/p&gt;

&lt;p&gt;To be honest, the most time I spent was on trying different syntax highlighting libs and got no results :D&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Building desktop app is fun and easy, especially for small projects like mine. You should give it a try.&lt;/p&gt;

&lt;p&gt;Thanks for reading&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Step by step to install kubernetes cluster</title>
      <dc:creator>Mạnh Đạt</dc:creator>
      <pubDate>Mon, 07 Jun 2021 00:21:49 +0000</pubDate>
      <link>https://dev.to/datmt/step-by-step-to-install-kubernetes-cluster-1el4</link>
      <guid>https://dev.to/datmt/step-by-step-to-install-kubernetes-cluster-1el4</guid>
      <description>&lt;p&gt;This post was originally posted &lt;a href="https://datmt.com/linux/install-kubernetes-cluster-with-kubeadm-on-ubuntu-step-by-step/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;I've been trying installing a Kubernetes cluster for while following the official documentation without any success. It turned out the official documentation was missing some important steps (or they put the missing steps else where I couldn’t find). Anyways, if you are struggling to get a Kubernetes up and running, this step by step tutorial is for you.&lt;/p&gt;

&lt;p&gt;I’m going to setup a k8s cluster with 1 master node and 1 worker node. Once you have a master node up and running, adding one or more worker nodes does not require extra expertise.&lt;/p&gt;

&lt;p&gt;I also use VirtualBox running two identical Ubuntu 18.04 VM. I guess that the newer Ubuntu versions should work fine (haven’t tested).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step by step to install kubernetes cluster
&lt;/h2&gt;

&lt;p&gt;Here are the steps you need to run on all nodes&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Disable swap
&lt;/h3&gt;

&lt;p&gt;To disable swap, simply remove the line with swap in /etc/fstab&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;sudo &lt;/span&gt;vim /etc/fstab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Comment out the line with swap&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2021%2F06%2Fimage-12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2021%2F06%2Fimage-12.png" alt="disable swap"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 2: Install docker run time
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
 &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    apt-transport-https &lt;span class="se"&gt;\&lt;/span&gt;
    ca-certificates &lt;span class="se"&gt;\&lt;/span&gt;
    curl &lt;span class="se"&gt;\&lt;/span&gt;
    gnupg &lt;span class="se"&gt;\&lt;/span&gt;
    lsb-release

curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://download.docker.com/linux/ubuntu/gpg | &lt;span class="nb"&gt;sudo &lt;/span&gt;gpg &lt;span class="nt"&gt;--dearmor&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /usr/share/keyrings/docker-archive-keyring.gpg

 &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
 &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;docker-ce docker-ce-cli containerd.io

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

&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 3: Configure cgroup
&lt;/h3&gt;

&lt;p&gt;Switch to root and run&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;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/docker/daemon.json &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;systemctl restart docker

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Install kubeadm, kubelet, kubectl
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;curl &lt;span class="nt"&gt;-fsSLo&lt;/span&gt; /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/kubernetes.list

&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; kubelet kubeadm kubectl
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-mark hold kubelet kubeadm kubectl

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

&lt;/div&gt;



&lt;p&gt;Now, that's all the common commands you need to run on all nodes. Next comes the command you only run on the master node:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: start master node
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubeadm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see similar message after a few minutes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2021%2F06%2Fimage-8-1024x626.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2021%2F06%2Fimage-8-1024x626.png" alt="kubeadm init successfully"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the &lt;code&gt;kubeadm join...&lt;/code&gt; command to later run on worker nodes.&lt;/p&gt;

&lt;p&gt;Finally, you need to install network plugin for the master node (super important!)&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;sudo &lt;/span&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"https://cloud.weave.works/k8s/net?k8s-version=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;kubectl version | &lt;span class="nb"&gt;base64&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'\n'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait for a few minutes for the master node to be ready. You can run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl cluster-info
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and wait until the status of the master node is &lt;code&gt;Ready&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Join the cluster on worker nodes
&lt;/h3&gt;

&lt;p&gt;Then, switch to the worker node and run the join command (the one you got after &lt;code&gt;kubeadm init&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubeadm &lt;span class="nb"&gt;join &lt;/span&gt;192.168.1.98:6443 &lt;span class="nt"&gt;--token&lt;/span&gt; 0mfz2s.4xt0waiyfnpxiyt9 &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--discovery-token-ca-cert-hash&lt;/span&gt; sha256:12e48d3bbfb435536618fc293a77950c13ac975fbea934c49c39abe4b7335ce1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Back to the master node and run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;watch kubectl get nodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will watch the cluster and after a few minutes, you should see all the nodes are ready:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2021%2F06%2Fimage-11-1024x629.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdatmt.com%2Fwp-content%2Fuploads%2F2021%2F06%2Fimage-11-1024x629.png" alt="Cluster nodes area ready"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You have successfully setup a kubernetes cluster&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>cloud</category>
      <category>docker</category>
    </item>
    <item>
      <title>Create Lumen development environment in 1 minute</title>
      <dc:creator>Mạnh Đạt</dc:creator>
      <pubDate>Tue, 12 Jan 2021 09:11:36 +0000</pubDate>
      <link>https://dev.to/datmt/create-lumen-development-environment-in-1-minute-5gf9</link>
      <guid>https://dev.to/datmt/create-lumen-development-environment-in-1-minute-5gf9</guid>
      <description>&lt;p&gt;So recently I need to study lumen (from Laravel). I used Laravel back in version 4.2. A lot of things has changed. I need to setup the environment very quickly and dive right into writing application. &lt;/p&gt;

&lt;p&gt;Having not so pleasant setting up Laravel (with Homestead, Vagrant...) I decide to find a method that help me (and other people like me) to get started quickly. After a few hours, I finally have the setup I really like.&lt;/p&gt;

&lt;p&gt;TLDR:&lt;br&gt;
Here is the video:&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=nympC_8CWwE&amp;amp;feature=youtu.be" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=nympC_8CWwE&amp;amp;feature=youtu.be&lt;/a&gt;&lt;br&gt;
Here is the git repo:&lt;br&gt;
&lt;a href="https://github.com/datmt/docker-microservices" rel="noopener noreferrer"&gt;https://github.com/datmt/docker-microservices&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the patient reader, read on.&lt;/p&gt;
&lt;h1&gt;
  
  
  Step 0: Clone the repo
&lt;/h1&gt;

&lt;p&gt;This is a must.&lt;/p&gt;
&lt;h1&gt;
  
  
  Step 1: choose a domain name, put in your hosts file.
&lt;/h1&gt;

&lt;p&gt;Don't worry, you don't need to buy any domain. You can pick any domain, even &lt;code&gt;google.com&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;In  my case, I used &lt;code&gt;cnn.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ft8vmbhly1zsilrpvtoud.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ft8vmbhly1zsilrpvtoud.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Step 2: Update the domain in default.conf file
&lt;/h1&gt;

&lt;p&gt;Now, in the lumen-dev folder, there is a file called default.conf. This is the default configuration for nginx server. &lt;/p&gt;

&lt;p&gt;Find the part says &lt;code&gt;cnn.com&lt;/code&gt; and replace it with your own domain.&lt;/p&gt;

&lt;p&gt;This is the content of the default.conf file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    root   /usr/share/nginx/html;

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php_server:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
    # concurs with nginx's one
    #
    location ~ /\.ht {
        deny  all;
    }
}


server {
    listen 80 default_server;


    root /usr/share/nginx/html/public;
    index index.php index.html index.htm;

    server_name cnn.com;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php_server:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }


}

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

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 3: Install composer packages
&lt;/h1&gt;

&lt;p&gt;cd to &lt;code&gt;src&lt;/code&gt; folder and run &lt;code&gt;composer install&lt;/code&gt;. In case you don't have composer installed, download the &lt;code&gt;lumen.tar.gz&lt;/code&gt; file under &lt;code&gt;archives&lt;/code&gt; and extract it. There is a vendor folder there. &lt;br&gt;
Copy that vendor folder to &lt;code&gt;src/&lt;/code&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Step 4: Edit your port
&lt;/h1&gt;

&lt;p&gt;My default configuration use port 8089. If you want to use other port, change it accordingly. One caution if you use port 80 is to make sure that port is free. Many applications use port 80 so you may not be able to start the application.&lt;br&gt;
This is the docker-compose.yml file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3.8'

services:
    nginx:
        image: nginx:1.19.6
        container_name: nginx
        volumes:
            - ./src:/usr/share/nginx/html
            - ./default.conf:/etc/nginx/conf.d/default.conf
        ports:
            - 8089:80
        links:
            - php_server
    php_server:
        container_name: php_server
        image: php:7.4.14-fpm-buster
        volumes:
            - ./src:/usr/share/nginx/html


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

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 5: Use docker-compose to start the app
&lt;/h1&gt;

&lt;p&gt;In &lt;code&gt;lumen-dev&lt;/code&gt; folder (where you have docker-compose.yml file), run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose up -d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can open your browser and access your application at the port you choose. &lt;/p&gt;

&lt;p&gt;Have questions? Please let me know&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>webdev</category>
      <category>docker</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
