<?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: Pankaj Gupta</title>
    <description>The latest articles on DEV Community by Pankaj Gupta (@pankajgupta221b).</description>
    <link>https://dev.to/pankajgupta221b</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%2F1245168%2F446694f3-0df8-4cf5-8e19-4355f034ee52.jpg</url>
      <title>DEV Community: Pankaj Gupta</title>
      <link>https://dev.to/pankajgupta221b</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pankajgupta221b"/>
    <language>en</language>
    <item>
      <title>Consistency &gt;&gt;&gt; Talent</title>
      <dc:creator>Pankaj Gupta</dc:creator>
      <pubDate>Sun, 07 Apr 2024 18:57:22 +0000</pubDate>
      <link>https://dev.to/pankajgupta221b/consistency-talent-3c8f</link>
      <guid>https://dev.to/pankajgupta221b/consistency-talent-3c8f</guid>
      <description>&lt;p&gt;I've been working in the field for 7 years now, and I wish I had someone in my life, a mentor if you will, who told me that consistency is much more appreciated and valued than talent.&lt;/p&gt;

&lt;p&gt;I have to set something straight before I go on and tell you a story about it. When I say 'Talent,' I mean the exceptional people who are born to do this, not someone who doesn't want to accept they are not the best.&lt;/p&gt;




&lt;p&gt;I had a hemi shoulder replacement on May 19th, 2023. The days that followed were the most painful days of my life. On the first day, the physios were trying to bring some movement, and due to the post-anesthetic effect, I couldn't feel anything. As soon as the anesthetic effect started fading, the shoulder felt like a block of ice. I had only 15 degrees of movement.&lt;/p&gt;

&lt;p&gt;Every day, I regretted getting the replacement. It used to be the worst hour of the day for me when the physio visited the house. It felt like trying to bend a block of metal and hurt like hell. After the first week, without my realization, my movement had increased by 10 degrees, and now I could lift my hands higher. It felt good, but no matter how good I felt that day, the next day it would hurt like hell again. Every other week, out of nowhere, I could see some improvements. Weeks turned into months, and I found myself training with weights. Weights helped during the lying down position exercises and made it worse during the ones where I had to stand up. I was able to lift my hands about 140 degrees standing up at the end of 2 months.&lt;/p&gt;

&lt;p&gt;The last few degrees were the most difficult to achieve; the pain was minimal by then, but to achieve each degree of movement, I had to work many times harder. On the last day of physiotherapy, I had a normally functioning shoulder. It took about 3 months.&lt;/p&gt;

&lt;p&gt;I had joined back at work after 2 weeks after surgery, and Baani (my daughter) was 7 months old at the time. I never thought about the pain and suffering I went through again. During one of the visits a couple of months later, my doctor told me I was the first patient of the physio who visited my house, and out of the 4 similar patients in that time frame, I was the only one with almost complete movements. My physio had earned a promotion with the help of my case.&lt;/p&gt;




&lt;p&gt;It hit me. If I had asked my physio about the other patients and learned that they were not getting past this stage of movements, I would have also given up along the way. If I had information that they were not consistent, I would have as well taken some days off here and there. I would have somehow found a way to not work as hard as I did.&lt;/p&gt;




&lt;p&gt;I realized my recovery experiences can be very good life lessons for everyone, including myself.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be consistent, set small goals, and achieve your targets regularly.&lt;/li&gt;
&lt;li&gt;Don't compare yourself with others; it might have a negative impact on your performance.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Now, imagine you lead a tech team. You have two engineers in your team: one is an average engineer who is consistent and keeps everything up-to-date, attends every meeting, and updates you regularly on delays and other things. The other is brilliant, but his work fluctuates based on multiple factors. Some days he'll come up with brilliant solutions, but due to a lack of planning and consistency, he'll end up delaying the project.&lt;/p&gt;

&lt;p&gt;A lot of people, including myself, fall into the second category. According to me, I was coming up with solutions, and nothing with me was wrong, but the reality is different.&lt;/p&gt;

&lt;p&gt;If I were leading a team with two people like this, I would always rely on the first person, as I would always have more control over the situation.&lt;/p&gt;




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

&lt;p&gt;Everyone needs someone to look up to and someone who can mentor them. If you need such help in your career, I am available. Please leave a comment and let me know.&lt;/p&gt;

</description>
      <category>career</category>
    </item>
    <item>
      <title>Including Polymorphic Association In Rails To Avoid N+1 Queries</title>
      <dc:creator>Pankaj Gupta</dc:creator>
      <pubDate>Sun, 04 Feb 2024 02:32:33 +0000</pubDate>
      <link>https://dev.to/pankajgupta221b/including-polymorphic-association-in-rails-to-avoid-n1-queries-5agh</link>
      <guid>https://dev.to/pankajgupta221b/including-polymorphic-association-in-rails-to-avoid-n1-queries-5agh</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Polymorphic association is a more advanced type of association where a model can belong to one or more models. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;polymorphic: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Note&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:documents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;as: :object&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Story&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:documents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;as: :object&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Problem Statement
&lt;/h2&gt;

&lt;p&gt;When querying the notes model, it is easier to include the associated documents because your model knows that there is only one model related to the documents. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#note_ids is a list of note ids&lt;/span&gt;
&lt;span class="n"&gt;notes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:documents&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;id: &lt;/span&gt;&lt;span class="n"&gt;note_ids&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pluck&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:object_id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;documents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;flat_map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;documents&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will execute two queries, one on the notes and one on the documents model. It seems straightforward, but if you want to achieve the same thing from the other way around, let's see what happens:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:notes&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;id: &lt;/span&gt;&lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will throw an ActiveRecord::AssociationNotFoundError: Association named 'notes' was not found on Document; perhaps you misspelled it? error, which seems fair because we haven't declared anything on the Document model corresponding to the Note model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;We need to do that first of all, and let's see how it goes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:note&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After including this and running this again, we get a surprising result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:note&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;id: &lt;/span&gt;&lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# request on notes&lt;/span&gt;
&lt;span class="no"&gt;SELECT&lt;/span&gt; &lt;span class="s2"&gt;"notes"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;*&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="s2"&gt;"notes"&lt;/span&gt; &lt;span class="no"&gt;WHERE&lt;/span&gt; &lt;span class="s2"&gt;"notes"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$1&lt;/span&gt;  &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This throws 2 DB requests, but it is not able to pick up the id for the notes somehow. If we provide the foreign key column, things might work in our favor, let's see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:note&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;foreign_key: &lt;/span&gt;&lt;span class="s2"&gt;"object_id"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if we check the queries, we get something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:note&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;id: &lt;/span&gt;&lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;first&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="c1"&gt;# query on the Document model&lt;/span&gt;
&lt;span class="no"&gt;Document&lt;/span&gt; &lt;span class="no"&gt;Load&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;216.8&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="no"&gt;SELECT&lt;/span&gt; &lt;span class="s2"&gt;"documents"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;*&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="s2"&gt;"documents"&lt;/span&gt; &lt;span class="no"&gt;WHERE&lt;/span&gt; &lt;span class="s2"&gt;"documents"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt; &lt;span class="no"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vg"&gt;$1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vg"&gt;$2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;26954&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;26955&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;

&lt;span class="c1"&gt;# query on the Note&lt;/span&gt;
&lt;span class="no"&gt;Note&lt;/span&gt; &lt;span class="no"&gt;Load&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;215.3&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="no"&gt;SELECT&lt;/span&gt; &lt;span class="s2"&gt;"notes"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;*&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="s2"&gt;"notes"&lt;/span&gt; &lt;span class="no"&gt;WHERE&lt;/span&gt; &lt;span class="s2"&gt;"notes"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt; &lt;span class="no"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vg"&gt;$1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vg"&gt;$2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;68057&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;68058&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We were able to reduce the N + 1 queries, but there is still an issue. It is querying for all the types, not just Note.&lt;/p&gt;

&lt;p&gt;This would be a significant problem because this is not reliable at all. Imagine the consequences. To solve this issue, we have to use the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;has_one&lt;/span&gt; &lt;span class="ss"&gt;:self_ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class_name: &lt;/span&gt;&lt;span class="s1"&gt;'Document'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;foreign_key: :id&lt;/span&gt;

&lt;span class="n"&gt;has_one&lt;/span&gt; &lt;span class="ss"&gt;:note&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;through: :self_ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;source: :object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;source_type: &lt;/span&gt;&lt;span class="s1"&gt;'Note'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, every time we include note, it will only query on the notes model and not any other model.&lt;/p&gt;

&lt;p&gt;Of course, the downside is you'll have to include all the models you want to query this way.&lt;/p&gt;

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

&lt;p&gt;There can be other ways to solve this problem. This is just one of the solution. Please feel free to explore and connect for other solutions.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>database</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How To Setup MongoDB Like a Pro</title>
      <dc:creator>Pankaj Gupta</dc:creator>
      <pubDate>Wed, 24 Jan 2024 07:46:28 +0000</pubDate>
      <link>https://dev.to/pankajgupta221b/mongodb-replicaset-for-beginners-48lm</link>
      <guid>https://dev.to/pankajgupta221b/mongodb-replicaset-for-beginners-48lm</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I started my career 6 years ago as a Frontend Engineer. We had mongoDB as our main database. Although I was a FE, I have  always been fascinated by how the fancier things like replication, caching actually works. I was too afraid to try it, hoping I would break the running things on my system and would have to spend a lot of time fixing that. The fear stopped me from trying a lot of things I wanted to try. Today we will be trying one of those things and break the shackles. &lt;/p&gt;

&lt;p&gt;We will be going through setting up mongoDB on your local machine and running multiple instance of it to setup replicaSet and how to add new machines and remove machine and all that, this skill can be directly transffered to a cloud based setup as well. &lt;/p&gt;

&lt;h2&gt;
  
  
  Installing MongoDB(community edition - 6.0)
&lt;/h2&gt;

&lt;p&gt;Installing MongoDB DB can be varied based on your local machine. You can follow the steps below if you are using Ubuntu 22.04 otherwise you can follow this guide &lt;a href="https://www.mongodb.com/docs/v6.0/administration/install-community/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;MongoDB only supports the 64-bit versions of these platforms. To determine which Ubuntu release your host is running, run the following command on the host's terminal:&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; /etc/lsb-release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Import the public key used by the package management system
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# install gnupg and curl if they are not already available&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;gnupg curl

&lt;span class="c"&gt;# import the MongoDB public GPG key&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://pgp.mongodb.com/server-6.0.asc | &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nb"&gt;sudo &lt;/span&gt;gpg &lt;span class="nt"&gt;-o&lt;/span&gt; /usr/share/keyrings/mongodb-server-6.0.gpg &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--dearmor&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a list file for MongoDB
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-6.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/6.0 multiverse"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/mongodb-org-6.0.list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Reload local package database
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Install the MongoDB Package
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="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; mongodb-org
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If there was no error, you would have successfully installed mongod and mongosh CLI Tools.&lt;/p&gt;

&lt;p&gt;I ran into some issues, I will mention the StackOverflow links here which helped me with the issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://stackoverflow.com/questions/28945921/e-unable-to-locate-package-mongodb-org"&gt;Unable to locate package mongodb-org&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;You can try to install the package, mongodb instead of monggodb-org. It is the unofficially package.&lt;/li&gt;
&lt;li&gt;I was installing the version 7 which is the latest, but I chose to used the previous version and the issue was solved.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Getting comfortable with &lt;code&gt;mongod&lt;/code&gt; and &lt;code&gt;mongosh&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;If you are running a Mac, you'll most likely be using brew to install all the background services and running them. You can use the similar commands in Ubuntu as well using systemd to run the services in daemon mode or in background.&lt;/p&gt;

&lt;h3&gt;
  
  
  Starting the service
&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;systemctl start mongod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should start the &lt;code&gt;mongod&lt;/code&gt; on port 27017, If you run into any issues, you'll have to debug the issue.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stopping the service
&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;systemctl stop mongod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Restarting the service
&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;systemctl restart mongod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Connecting to a &lt;code&gt;mongod&lt;/code&gt; instance with &lt;code&gt;mongosh&lt;/code&gt;
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;p&gt;You'll be taken into the shell and you'll be connected to test db by default and you can experiment all you want with it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Running &lt;code&gt;mongod&lt;/code&gt; in foreground
&lt;/h2&gt;

&lt;p&gt;You can run mongod on the foreground as well. No matter where you run it from background or foreground, it knows where to store the data, it knows where to write the logs, it knows what port to start on. How does it know? The secret is &lt;code&gt;/etc/mongod.conf&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Now if you cat /etc/mongod.conf file, you'll get something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# mongod.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# Where and how to store data.
storage:
  dbPath: /var/lib/mongodb
#  engine:
#  wiredTiger:

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

# network interfaces
net:
  port: 27017
  bindIp: 127.0.0.1


# how the process runs
processManagement:
  timeZoneInfo: /usr/share/zoneinfo

#security:

#operationProfiling:

#replication:

#sharding:

## Enterprise-Only Options:

#auditLog:

#snmp:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the beginners, there are 2 important things mentioned in this file: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;storage.dbPath&lt;/li&gt;
&lt;li&gt;net.port&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  storage.dbPath
&lt;/h4&gt;

&lt;p&gt;It refers to a directory, where mongo will be storing all the data.&lt;/p&gt;

&lt;h4&gt;
  
  
  net.port
&lt;/h4&gt;

&lt;p&gt;It refers to a port, on which the mongod will start.&lt;/p&gt;




&lt;p&gt;It is because of this conf file, you can't start multiple mongod instance. You can try starting two mongod instances on two terminal windows and it'll give a port error, mentioning the port is already occupied.&lt;/p&gt;

&lt;p&gt;The good thing is now we know what are the keys and we have an option to overwrite these keys with our values. Lets explore that option.&lt;/p&gt;




&lt;h2&gt;
  
  
  Starting &lt;code&gt;mongosh&lt;/code&gt; with different arguments
&lt;/h2&gt;

&lt;p&gt;When you start mongod, it picks the default port from /etc/mongod.conf file, which is 27017. In order to start the mongod on a different port, either you can update the mongod.conf file to use a different port or you can provide command line argument 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;mongod &lt;span class="nt"&gt;--port&lt;/span&gt; 27019
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this command you'll be able to start the mongod on port 27019.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep in mind to connect to this instance using mongosh, you'll need to pass the port as well using --port&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It also picks up a default location of the db. You can pass in the &lt;code&gt;dbPath&lt;/code&gt; to override that as well. Before we do that lets make a directory call mongo-dbs and create db1, db2 and db3 directory inside of it and start 3 different instance of mongo on different ports and dbs separate from each other.&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;mkdir &lt;/span&gt;mongo-dbs
&lt;span class="nb"&gt;cd &lt;/span&gt;mongo-dbs
&lt;span class="nb"&gt;mkdir &lt;/span&gt;db1
&lt;span class="nb"&gt;mkdir &lt;/span&gt;db2
&lt;span class="nb"&gt;mkdir &lt;/span&gt;db3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now in the first terminal, type in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mongod &lt;span class="nt"&gt;--dbpath&lt;/span&gt; ./db1 &lt;span class="nt"&gt;--port&lt;/span&gt; 27020
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the second terminal type in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mongod &lt;span class="nt"&gt;--dbpath&lt;/span&gt; ./db2 &lt;span class="nt"&gt;--port&lt;/span&gt; 27021
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the third terminal, type in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mongod &lt;span class="nt"&gt;--dbpath&lt;/span&gt; ./db3 &lt;span class="nt"&gt;--port&lt;/span&gt; 27022
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have three different instances of mongod running, you can connect to each of them using mongosh --port .&lt;/p&gt;




&lt;h2&gt;
  
  
  Replication
&lt;/h2&gt;

&lt;p&gt;If you have made it this far in the blog, congratulations. Lets see how the replication works in mongodb and setup a master - slave - slave replication.&lt;/p&gt;

&lt;p&gt;If you see the mongod.conf file, you'll see:&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;#replication:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That means by default the mongod doesn't have any replication setup.&lt;/p&gt;

&lt;p&gt;Inorder to setup mongod as replicas, we need to start it in a replication mode and give the replica a name. You can do that by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mongod &lt;span class="nt"&gt;--dbpath&lt;/span&gt; ./db1 &lt;span class="nt"&gt;--port&lt;/span&gt; 27020 &lt;span class="nt"&gt;--replSet&lt;/span&gt; my_replica
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you can start the other instances as well in the same manner keeping the name my_replica consistent.&lt;/p&gt;

&lt;p&gt;Once all the instances are running choose which mongod you want as primary and log on to that instance with mongosh --port .&lt;/p&gt;

&lt;p&gt;Now type in the command to initiate the replication:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This should give an acknowledgement that the replication has been started. In order check the status of the replicaSet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rs.status()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It throw out something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  set: 'myreplica',
  date: ISODate('2024-01-24T07:07:53.872Z'),
  myState: 1,
  term: Long('6'),
  syncSourceHost: '',
  syncSourceId: -1,
  heartbeatIntervalMillis: Long('2000'),
  majorityVoteCount: 2,
  writeMajorityCount: 2,
  votingMembersCount: 3,
  writableVotingMembersCount: 3,
  optimes: {...},
  lastStableRecoveryTimestamp: Timestamp({ t: 1706080036, i: 1 }),
  electionCandidateMetrics: {...},
  electionParticipantMetrics: {...},
  members: [
    {
      _id: 0,
      name: 'localhost:27020',
      health: 1,
      state: 1,
      stateStr: 'PRIMARY',
      uptime: 2800,
      optime: { ts: Timestamp({ t: 1706080066, i: 1 }), t: Long('6') },
      optimeDate: ISODate('2024-01-24T07:07:46.000Z'),
      lastAppliedWallTime: ISODate('2024-01-24T07:07:46.580Z'),
      lastDurableWallTime: ISODate('2024-01-24T07:07:46.580Z'),
      syncSourceHost: '',
      syncSourceId: -1,
      infoMessage: '',
      electionTime: Timestamp({ t: 1706078026, i: 1 }),
      electionDate: ISODate('2024-01-24T06:33:46.000Z'),
      configVersion: 5,
      configTerm: 6,
      self: true,
      lastHeartbeatMessage: ''
    }
  ],
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1706080066, i: 1 }),
    signature: {
      hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),
      keyId: Long('0')
    }
  },
  operationTime: Timestamp({ t: 1706080066, i: 1 })
}

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

&lt;/div&gt;



&lt;p&gt;If everything has worked for you till now, congratulations. Now we will be adding new members to this replicaSet. To add a new member:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rs.add('localhost:27021')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will also give an acknowledgement that a member has been added. Now if you check the status of the replicaSet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rs.status()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You have two members marked: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;stateStr: 'PRIMARY' and the other as stateStr: 'SECONDARY'&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Denoting the primary and the secondary instances. Secondary will also have one key&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;syncSourceHost: 'localhost:27020'&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Denoting which instance it will sync the data from. In the similar fashion, you can add the last instance as a member of this replicaSet and check the status. &lt;/p&gt;

&lt;p&gt;Now if you add any data in the primary member it'll automatically be synced to the secondary members.&lt;/p&gt;




&lt;h2&gt;
  
  
  Production Setup
&lt;/h2&gt;

&lt;p&gt;We have learned a lot of stuff, and it can be very daunting to try this for the first time. Lets expand this knowledge and move from local to production. &lt;/p&gt;

&lt;p&gt;We replicate data, to increase our availability, so if somehting happens to one instance other instances are running. Replicating data on same machine would mean if something wrong happens to the machine like power outage etc, the whole database would stop responding to requests.&lt;/p&gt;

&lt;p&gt;So in production we have multiple machines, and we have update the mongod.conf file on each of the machine to setup replication.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things to explore
&lt;/h2&gt;

&lt;p&gt;I want you to explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happens when you shut off a instance?&lt;/li&gt;
&lt;li&gt;Suppose we have data in the instances already, and you add a blank member, what will happen. &lt;/li&gt;
&lt;li&gt;What happens when a primary member is not working?
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>mongodb</category>
      <category>database</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Object Oriented Express API</title>
      <dc:creator>Pankaj Gupta</dc:creator>
      <pubDate>Fri, 19 Jan 2024 01:51:24 +0000</pubDate>
      <link>https://dev.to/pankajgupta221b/object-oriented-express-api-14hf</link>
      <guid>https://dev.to/pankajgupta221b/object-oriented-express-api-14hf</guid>
      <description>&lt;p&gt;I've been toying around with the idea of having a scalable express api service, which will handle some of the basic crud operations for a model without writing the actual code for the controller. I've three years of experience and I was not sure if you could something like that but then something happened.&lt;/p&gt;

&lt;p&gt;I started to work on Ruby on Rails last year and my perspective has been changed a lot since then, working on different tech stacks, with different people really opens you up. Someone had written a generic handler for all the models and all the basic operations of CRUD were handled without writing a piece of code for the new controller. It was then I realised the power of Object Oriented Programming.&lt;/p&gt;

&lt;p&gt;There are a lots of language specific perks of writing code in Ruby, but Object Orientation is a fundamental concept which can be very useful, so I decided to use it in Node and Express and make my first worthwhile contribution to the Open Source Community. I choose Node and Express because I have worked on it before and wanted to see the difference in the quality of code, In other words, I wanted to see how my skills have improved over the years.&lt;/p&gt;

&lt;p&gt;I started the project on a Saturday afternoon, I was almost done on Sunday. During the project, I found out some important things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In Express 5, which is currently a beta version, you don't have to throw the error explicitly, It throws the error itself and call the next() with the error, so no more if this then that in the handlers.&lt;/li&gt;
&lt;li&gt;You can use a whole javascript class as a route handler. (AMAZING!!)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It had to dig a bit to find these two solutions. Now with the help of these two solutions my handlers were looking something like this.&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Book&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../models/Book&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../caches/book.cache&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./base.controller&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// All the routes declared here!&lt;/span&gt;
    &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BookController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use this in your routes as this:&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;booksRouter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../controllers/book.controller&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/books&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;booksRouter&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;Isn't this neat and clean? As you can see I've imported the Model, and a cache class I've implemented for this. If you look closely you'll realize how is this working. Thats the best part. I've implemented a base controller which can be extented to every controller and they can use the methods defined in the base controller to implement the basic crud.&lt;/p&gt;

&lt;p&gt;The base controller looks something like this:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resources&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apiSend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;orFail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NotFoundError&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apiSend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;create&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apiSend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;apiSend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;json&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="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As You can see there is nothing specific to any model or controller. If you have a create method method which needs a bit of manipulations of post changes, You can implement that in your new controller using a service module specific to the controller or the model.&lt;/p&gt;

&lt;p&gt;A important point to notice is there is no try catch blocks in any of the handlers, it's the magic of express 5.&lt;/p&gt;

&lt;p&gt;If you guys are interested you can check it out &lt;a href="https://github.com/Pkfication/vanilla-express"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This project still needs a lot of improvements, but I am happy that it started this way! I'll keep posting further updates.&lt;/p&gt;

</description>
      <category>oop</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Querying MongoDB Like an SQL DB Using Aggregation Pipeline</title>
      <dc:creator>Pankaj Gupta</dc:creator>
      <pubDate>Mon, 15 Jan 2024 02:15:59 +0000</pubDate>
      <link>https://dev.to/pankajgupta221b/querying-mongodb-like-an-sql-db-using-aggregation-pipeline-ki6</link>
      <guid>https://dev.to/pankajgupta221b/querying-mongodb-like-an-sql-db-using-aggregation-pipeline-ki6</guid>
      <description>&lt;h2&gt;
  
  
  What Are Aggregations?
&lt;/h2&gt;

&lt;p&gt;Aggregation operations process data records and return computed results. Aggregation operations group values from multiple documents together and can perform a variety of operations on the grouped data to return a single result.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;db.collection.aggregate&lt;/code&gt; method and &lt;code&gt;db.aggregate&lt;/code&gt; method, &lt;a href="https://www.mongodb.com/docs/manual/core/aggregation-pipeline/"&gt;pipeline&lt;/a&gt; stages appear in an array. Documents pass through the stages in sequence. We will go through some of the stages to achieve a relational DB like results.&lt;/p&gt;




&lt;h3&gt;
  
  
  $match (WHERE)
&lt;/h3&gt;

&lt;p&gt;Filters the documents to pass only the documents that match the specified condition(s) to the next pipeline stage.&lt;/p&gt;

&lt;p&gt;It has the following prototype:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ $match: { &amp;lt;query&amp;gt; } }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is the equivalent of WHERE in SQL queries. Let us take an example to make things clear. This example uses a collection named &lt;code&gt;articles&lt;/code&gt; with the following documents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ "_id" : ObjectId("512bc95fe835e68f199c8686"), "author" : "dave", "score" : 80, "views" : 100 }
{ "_id" : ObjectId("512bc962e835e68f199c8687"), "author" : "dave", "score" : 85, "views" : 521 }
{ "_id" : ObjectId("55f5a192d4bede9ac365b257"), "author" : "ahn", "score" : 60, "views" : 1000 }
{ "_id" : ObjectId("55f5a192d4bede9ac365b258"), "author" : "li", "score" : 55, "views" : 5000 }
{ "_id" : ObjectId("55f5a1d3d4bede9ac365b259"), "author" : "annT", "score" : 60, "views" : 50 }
{ "_id" : ObjectId("55f5a1d3d4bede9ac365b25a"), "author" : "li", "score" : 94, "views" : 999 }
{ "_id" : ObjectId("55f5a1d3d4bede9ac365b25b"), "author" : "ty", "score" : 95, "views" : 1000 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Equality match.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.articles.aggregate(
    [ { $match : { author : "dave" } } ]
);
// Result
{ "_id" : ObjectId("512bc95fe835e68f199c8686"), "author" : "dave", "score" : 80, "views" : 100 }
{ "_id" : ObjectId("512bc962e835e68f199c8687"), "author" : "dave", "score" : 85, "views" : 521 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can have multiple constraints inside $match, like $or, $and, etc. according to our requirements, although it has some limitations as well. You can read about it in the Mongo &lt;a href="https://www.mongodb.com/docs/manual/reference/operator/aggregation/match/"&gt;docs&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  $skip (OFFSET)
&lt;/h2&gt;

&lt;p&gt;Skips over the specified number of &lt;a href="https://www.mongodb.com/docs/manual/reference/glossary/#term-document"&gt;documents&lt;/a&gt; that pass into the stage and passes the remaining documents to the next stage in the &lt;a href="https://www.mongodb.com/docs/manual/reference/glossary/#term-pipeline"&gt;pipeline&lt;/a&gt;. It has the following prototype:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ $skip: &amp;lt;positive integer&amp;gt; }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, we were able to match the records related to &lt;code&gt;dave&lt;/code&gt;. If we want to skip the few results from the beginning we would write the query as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.articles.aggregate([ 
    { $match : { author : "dave" } },
    { $skip: 1 } 
]);
// We are skipping 1 result and we should get just this
{ "_id" : ObjectId("5dc1d22f24a8e913bfcf4f60"), "author" : "dave", "score" : 85, "views" : 521 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We generally use &lt;code&gt;$skip&lt;/code&gt; with $&lt;code&gt;limit&lt;/code&gt; to paginate the data, let’s insert few more records into our collection and see how $&lt;code&gt;skip&lt;/code&gt; and $&lt;code&gt;limit&lt;/code&gt; work together in the next section.&lt;/p&gt;




&lt;h3&gt;
  
  
  $limit (LIMIT)
&lt;/h3&gt;

&lt;p&gt;Limits the number of documents passed to the next stage in the &lt;a href="https://www.mongodb.com/docs/manual/core/aggregation-pipeline/"&gt;pipeline&lt;/a&gt;. It has the following prototype:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ $limit: &amp;lt;positive integer&amp;gt; }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have added new records for &lt;code&gt;dave&lt;/code&gt;, let’s see how the collections look with a simple &lt;code&gt;$match&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.articles.aggregate(
    [ { $match : { author : "dave" } } ]
);
{ "_id" : ObjectId("5dc1d22124a8e913bfcf4f5f"), "author" : "dave", "score" : 80, "views" : 100 }
{ "_id" : ObjectId("5dc1d22f24a8e913bfcf4f60"), "author" : "dave", "score" : 85, "views" : 521 }
{ "_id" : ObjectId("5dc1d53924a8e913bfcf4f65"), "author" : "dave", "score" : 185, "views" : 1521 }
{ "_id" : ObjectId("5dc1d54f24a8e913bfcf4f66"), "author" : "dave", "score" : 15, "views" : 21 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have four matching records in the example collection. Suppose you are asked to paginate the results to show two at a time, how would you go about it? Let’s see.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.articles.aggregate([ 
    { $match : { author : "dave" } },
    { $skip: 0},
    { $limit: 2}
]);
// We are not skipping any records and but limiting the records to 2
{ "_id" : ObjectId("5dc1d22124a8e913bfcf4f5f"), "author" : "dave", "score" : 80, "views" : 100 }
{ "_id" : ObjectId("5dc1d22f24a8e913bfcf4f60"), "author" : "dave", "score" : 85, "views" : 521 }
// We got the first two results, to get the next two results just update the $skip
db.articles.aggregate([ 
    { $match : { author : "dave" } },
    { $skip: 2},
    { $limit: 2}
]);
// This should give two records after skipping the first two.
{ "_id" : ObjectId("5dc1d53924a8e913bfcf4f65"), "author" : "dave", "score" : 185, "views" : 1521 }
{ "_id" : ObjectId("5dc1d54f24a8e913bfcf4f66"), "author" : "dave", "score" : 15, "views" : 21 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are doing good so far, but suppose your manager comes up to you and asks you to sort the result by views. What are you going to do? We have &lt;code&gt;$sort&lt;/code&gt; for that.&lt;/p&gt;




&lt;h3&gt;
  
  
  $sort (ORDER BY)
&lt;/h3&gt;

&lt;p&gt;Sorts all input documents and returns them to the &lt;a href="https://www.mongodb.com/docs/manual/core/aggregation-pipeline/"&gt;https://www.mongodb.com/docs/manual/core/aggregation-pipeline/&lt;/a&gt; in sorted order. It has the following prototype:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ $sort: { &amp;lt;field1&amp;gt;: &amp;lt;sort order&amp;gt;, &amp;lt;field2&amp;gt;: &amp;lt;sort order&amp;gt; ... } }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let us use the &lt;code&gt;$sort&lt;/code&gt; stage in our pipeline.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 to specify ascending order
-1 to specify descending order
db.articles.aggregate([ 
    { $match : { author : "dave" } },
    { $sort: { views: 1}}
]);
// Result
{ "_id" : ObjectId("5dc1d54f24a8e913bfcf4f66"), "author" : "dave", "score" : 15, "views" : 21 }
{ "_id" : ObjectId("5dc1d22124a8e913bfcf4f5f"), "author" : "dave", "score" : 80, "views" : 100 }
{ "_id" : ObjectId("5dc1d22f24a8e913bfcf4f60"), "author" : "dave", "score" : 85, "views" : 521 }
{ "_id" : ObjectId("5dc1d53924a8e913bfcf4f65"), "author" : "dave", "score" : 185, "views" : 1521 }

Voilà ! The results are sorted now.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Place the &lt;code&gt;$match&lt;/code&gt; as early in the aggregation pipeline as possible. Because &lt;code&gt;$match&lt;/code&gt; limits the total number of documents in the aggregation pipeline, earlier &lt;code&gt;$match&lt;/code&gt; operations minimize the amount of processing down the pipe.&lt;/p&gt;




&lt;h3&gt;
  
  
  $group
&lt;/h3&gt;

&lt;p&gt;Groups input documents by the specified &lt;code&gt;_id&lt;/code&gt; expression and, for each distinct grouping, outputs a document.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;_id&lt;/code&gt; field of each output document contains the unique group by value. The output documents can also contain computed fields that hold the values of an &lt;a href="https://www.mongodb.com/docs/manual/reference/operator/aggregation/group/#accumulators-group"&gt;accumulator expression&lt;/a&gt;. It has the following prototype:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  $group:
    {
      _id: &amp;lt;expression&amp;gt;, // Group By Expression
      &amp;lt;field1&amp;gt;: { &amp;lt;accumulator1&amp;gt; : &amp;lt;expression1&amp;gt; },
      ...
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose we want to group the articles by author, in other words, the number of articles by each author, we can make use of the group stage in the pipeline. So, let’s see it live:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.articles.aggregate([ 
    { $group : { _id: "$author", count: { $sum: 1 }}},
    { $sort: { count: 1 }}
]);
// We have grouped the articles by author ann getting the count and sorting it by count
{ "_id" : "annT", "count" : 1 }
{ "_id" : "ahn", "count" : 1 }
{ "_id" : "li", "count" : 2 }
{ "_id" : "dave", "count" : 4 }
// We can have more constraints like if we want only the results whose count is greater than 1, then we can add a $match stage in the pipeline after $group
db.articles.aggregate([ 
    { $group : { _id: "$author", count: { $sum: 1 }}},
    { $sort: { count: 1 }},
    { $match: { count : { $gt: 1 }}}
]);
{ "_id" : "li", "count" : 2 }
{ "_id" : "dave", "count" : 4 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let us take this grouping up a notch. Suppose we want to group by values stored in an array structure. We have something called &lt;code&gt;$unwind&lt;/code&gt;. Let’s see how it works.&lt;/p&gt;




&lt;h3&gt;
  
  
  $unwind
&lt;/h3&gt;

&lt;p&gt;Deconstructs an array field from the input documents to output a document for each element. Each output document is the input document with the value of the array field replaced by the element.&lt;/p&gt;

&lt;p&gt;You can pass the array field path to &lt;code&gt;$unwind&lt;/code&gt;. When using this syntax, &lt;code&gt;$unwind&lt;/code&gt; does not output a document if the field value is null, missing, or an empty array. It has the following prototype:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ $unwind: &amp;lt;field path&amp;gt; }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let us take a new collection inventory and a new record to it with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.inventory.insertOne({ "_id" : 1, "item" : "ABC1", sizes: [ "S", "M", "L"] })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s the beauty of MongoDB, you can create a new collection and each document is identical to the input document, except for the value of the sizes field which now holds a value from the original sizes array. Add a record to it without any setup.&lt;/p&gt;

&lt;p&gt;Let us &lt;code&gt;$unwind&lt;/code&gt; this by the sizes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.inventory.aggregate( [ { $unwind : "$sizes" } ] )
// Result
{ "_id" : 1, "item" : "ABC1", "sizes" : "S" }
{ "_id" : 1, "item" : "ABC1", "sizes" : "M" }
{ "_id" : 1, "item" : "ABC1", "sizes" : "L" }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each document is identical to the input document except for the value of the sizes field which now holds a value from the original sizes array.&lt;/p&gt;

&lt;p&gt;Let us take a new collection inventory2 and do a group by the size, use this command to insert more records:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.inventory2.insertMany([
  { "_id" : 1, "item" : "ABC", price: NumberDecimal("80"), "sizes": [ "S", "M", "L"] },
  { "_id" : 2, "item" : "EFG", price: NumberDecimal("120"), "sizes" : [ ] },
  { "_id" : 3, "item" : "IJK", price: NumberDecimal("160"), "sizes": "M" },
  { "_id" : 4, "item" : "LMN" , price: NumberDecimal("10") },
  { "_id" : 5, "item" : "XYZ", price: NumberDecimal("5.75"), "sizes" : null }
])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we unwind this, we would get something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.inventory2.aggregate( [ { $unwind: "$sizes" } ] )
// Results
{ "_id" : 1, "item" : "ABC", "price" : NumberDecimal("80"), "sizes" : "S" }
{ "_id" : 1, "item" : "ABC", "price" : NumberDecimal("80"), "sizes" : "M" }
{ "_id" : 1, "item" : "ABC", "price" : NumberDecimal("80"), "sizes" : "L" }
{ "_id" : 3, "item" : "IJK", "price" : NumberDecimal("160"), "sizes" : "M" }
// Notice it ignores the null and undefined values
db.articles.aggregate([ 
    { $unwind: { path: "$sizes" } },
    { $group: { _id: "$sizes", count: { $sum: 1 }}}
]);
// Results
{ "_id" : "M", "count" : 2 }
{ "_id" : "L", "count" : 1 }
{ "_id" : "S", "count" : 1 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can apply different stages to this like &lt;code&gt;$match&lt;/code&gt;, &lt;code&gt;$sort&lt;/code&gt;, &lt;code&gt;$skip&lt;/code&gt;, &lt;code&gt;$limit&lt;/code&gt;, etc. to get the desired results.&lt;/p&gt;

&lt;p&gt;Now, let’s move on to SQL JOINS, to achieve joins in MongoDB we have &lt;code&gt;$lookup&lt;/code&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  $lookup
&lt;/h3&gt;

&lt;p&gt;New in version 3.2.&lt;/p&gt;

&lt;p&gt;Performs a left outer join to an unsharded collection in the same database to filter in documents from the “joined” collection for processing.&lt;/p&gt;

&lt;p&gt;To each input document, the &lt;code&gt;$lookup&lt;/code&gt; stage adds a new array field whose elements are the matching documents from the “joined” collection. The &lt;code&gt;$lookup&lt;/code&gt; stage passes these reshaped documents to the next stage.&lt;/p&gt;

&lt;p&gt;There can be different join conditions but we will be looking into the most basic one, which is an equality match.&lt;/p&gt;

&lt;h4&gt;
  
  
  Equality match
&lt;/h4&gt;

&lt;p&gt;To perform uncorrelated subqueries between two collections as well as allow other join conditions besides a single equality match. The &lt;code&gt;$lookup&lt;/code&gt; stage has the following syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
   $lookup:
     {
       from: &amp;lt;collection to join&amp;gt;,
       let: { &amp;lt;var_1&amp;gt;: &amp;lt;expression&amp;gt;, …, &amp;lt;var_n&amp;gt;: &amp;lt;expression&amp;gt; },
       pipeline: [ &amp;lt;pipeline to execute on the collection to join&amp;gt; ],
       as: &amp;lt;output array field&amp;gt;
     }
}
from: Specifies the collection in the same database to perform the join with.
let: Optional. Specifies variables to use in the pipeline field stages. Use the variable expressions to access the fields from the documents input to the $lookup stage.
pipeline: Specifies the pipeline to run on the joined collection. The pipeline determines the resulting documents from the joined collection. To return all documents, specify an empty pipeline [].
as: Specifies the name of the new array field to add to the input documents. The new array field contains the matching documents from the from collection. If the specified name already exists in the input document, the existing field is overwritten.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let us look at some examples to better understand the terminologies:&lt;/p&gt;

&lt;h4&gt;
  
  
  Perform a single equality join with $lookup
&lt;/h4&gt;

&lt;p&gt;Create a collection &lt;code&gt;orders&lt;/code&gt; with the following documents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.orders.insert([
   { "_id" : 1, "item" : "almonds", "price" : 12, "quantity" : 2 },
   { "_id" : 2, "item" : "pecans", "price" : 20, "quantity" : 1 },
   { "_id" : 3  }
])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create another collection &lt;code&gt;inventory&lt;/code&gt; with the following documents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.inventory.insert([
   { "_id" : 1, "sku" : "almonds", description: "product 1", "instock" : 120 },
   { "_id" : 2, "sku" : "bread", description: "product 2", "instock" : 80 },
   { "_id" : 3, "sku" : "cashews", description: "product 3", "instock" : 60 },
   { "_id" : 4, "sku" : "pecans", description: "product 4", "instock" : 70 },
   { "_id" : 5, "sku": null, description: "Incomplete" },
   { "_id" : 6 }
])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following aggregation operation on the orders collection joins the documents from &lt;code&gt;orders&lt;/code&gt; with the documents from the &lt;code&gt;inventory&lt;/code&gt; collection using the fields item from the orders collection and the sku field from the inventory collection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db.orders.aggregate([
   {
     $lookup:
       {
         from: "inventory",
         localField: "item",
         foreignField: "sku",
         as: "inventory_docs"
       }
  }
]);

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

&lt;/div&gt;



&lt;p&gt;The operation returns the following documents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
   "_id" : 1,
   "item" : "almonds",
   "price" : 12,
   "quantity" : 2,
   "inventory_docs" : [
      { "_id" : 1, "sku" : "almonds", "description" : "product 1", "instock" : 120 }
   ]
}
{
   "_id" : 2,
   "item" : "pecans",
   "price" : 20,
   "quantity" : 1,
   "inventory_docs" : [
      { "_id" : 4, "sku" : "pecans", "description" : "product 4", "instock" : 70 }
   ]
}
{
   "_id" : 3,
   "inventory_docs" : [
      { "_id" : 5, "sku" : null, "description" : "Incomplete" },
      { "_id" : 6 }
   ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This was just a basic overview of using SQL-like queries in MongoDB.&lt;/p&gt;

&lt;p&gt;There is a lot more that can be done using many other &lt;a href="https://www.mongodb.com/docs/manual/reference/operator/aggregation-pipeline/"&gt;stages&lt;/a&gt; that are available. The best way to have a good grasp of it is by practicing different scenarios and using them in your projects. I hope this will help.&lt;/p&gt;




&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.mongodb.com/docs/manual/reference/operator/aggregation-pipeline/"&gt;MongoDB Documentation&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>sql</category>
      <category>webdev</category>
      <category>database</category>
    </item>
    <item>
      <title>Understanding the Efficiency of vim</title>
      <dc:creator>Pankaj Gupta</dc:creator>
      <pubDate>Fri, 05 Jan 2024 07:13:13 +0000</pubDate>
      <link>https://dev.to/pankajgupta221b/understanding-the-efficiency-of-vim-5719</link>
      <guid>https://dev.to/pankajgupta221b/understanding-the-efficiency-of-vim-5719</guid>
      <description>&lt;h2&gt;
  
  
  Highlights of vim
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Ubiquitous — Shipped with every NIX Platform.&lt;/li&gt;
&lt;li&gt;Highly customizable — Can be tailored to your needs.&lt;/li&gt;
&lt;li&gt;Lightning-fast.&lt;/li&gt;
&lt;li&gt;Insanely efficient.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Basics
&lt;/h2&gt;

&lt;p&gt;Before we start learning how &lt;a href="https://www.vim.org/"&gt;vim&lt;/a&gt; works, I just want to mention some commands so that people who are new to vim can use it.&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;# Open a file in vim&lt;/span&gt;
vim textfile.text
&lt;span class="c"&gt;# Come out of vim&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;Esc]:q &lt;span class="c"&gt;# quit without saving&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;Esc]:wq &lt;span class="c"&gt;# save and quit&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;Esc]:q! &lt;span class="c"&gt;# discard changes and quit&lt;/span&gt;
&lt;span class="c"&gt;# Navigation&lt;/span&gt;
h &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; left
j &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; down
k &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; up
l &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; right
&lt;span class="c"&gt;# Copy&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;Esc]v[h|j|k|l]y &lt;span class="c"&gt;# h,j,k,l to highlight a block&lt;/span&gt;
&lt;span class="c"&gt;# Cut&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;Esc]v[h|j|k|l]d &lt;span class="c"&gt;# h,j,k,l to highlight a block&lt;/span&gt;
&lt;span class="c"&gt;# Paste&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;Esc]p
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why vim
&lt;/h2&gt;

&lt;p&gt;What distinguishes vim from other editors? It’s a modal editor that makes it so efficient. Unlike any other editors, that only have one mode which is insertion mode, you are constantly typing and streaming text into the buffer.&lt;/p&gt;

&lt;p&gt;Now, for writing this is great, however, as programmers, what we care about most isn’t constant flow of text but editing and navigating. I think the best analogy to explain this would be:&lt;/p&gt;

&lt;p&gt;You can imagine programmers as painters and painters don’t spend their time continuously doing one brush stroke, they prepare the canvas, mix up the colors, and then they do individual discrete strokes.&lt;/p&gt;

&lt;p&gt;Vim achieves this with different modes. Here are the four modes to get started with vim.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mf5z6SbT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pigwwauskzoen495ns5u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mf5z6SbT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pigwwauskzoen495ns5u.png" alt="4 different modes of vim" width="373" height="105"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Normal mode
&lt;/h3&gt;

&lt;p&gt;Here, we interact with text and tell it what to do. When we launch vim, this is the default mode.&lt;/p&gt;

&lt;p&gt;Most people are used to just typing, but in this mode, we don’t insert text into the buffer, we do other types of activities like navigation. We can get to this mode by pressing Esc. This is the default mode in vim.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Insert mode
&lt;/h3&gt;

&lt;p&gt;You can get into this mode using i: insert, a: append, c: change. This is the mode most people are used to. So, remember, if you open vim and want to type something, switch to the insert mode using the mentioned keystrokes.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Visual mode
&lt;/h3&gt;

&lt;p&gt;This is just like normal mode, except it works with highlighted blocks of texts. Another problem people face is copying and cutting text, you can do that in this mode. You can get here from normal mode using V, v, .&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Command-line mode
&lt;/h3&gt;

&lt;p&gt;This is where you find texts, exit vim, navigate files, and whatnot.&lt;/p&gt;




&lt;h2&gt;
  
  
  Operators, Text Objects, and Motions
&lt;/h2&gt;

&lt;p&gt;To use vim, you have to think in terms of Operators, text objects, and motions, then you will unleash the real power of vim.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Operators
&lt;/h3&gt;

&lt;p&gt;These are the verbs of the vim language. They specify actions to perform on your text objects or motions and most of them are easy to remember.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tbH5JF8e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p55atbgjpcavx7e19vhj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tbH5JF8e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p55atbgjpcavx7e19vhj.png" alt="Sample Operators" width="309" height="115"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Text objects
&lt;/h3&gt;

&lt;p&gt;These are the actual visual text on your screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oe4CGxuR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ob3tirkls9ouvwe677lv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oe4CGxuR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ob3tirkls9ouvwe677lv.png" alt="Sample Text Objects" width="375" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, very simple to remember: aw: a word. Now, here we can combine these with operators to see some powerful actions. Here are a few of my favorites:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--W4vIzzy1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ke1vc0ioxmhw3ql0oi0i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--W4vIzzy1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ke1vc0ioxmhw3ql0oi0i.png" alt="Combined Operators and Text Objects" width="314" height="107"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Motions
&lt;/h3&gt;

&lt;p&gt;Motions are all about efficient navigation through the file that you’ve opened. Here are some of the most useful motions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OZ5-tE2U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mzgwgb1ro8esicbpyfjo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OZ5-tE2U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mzgwgb1ro8esicbpyfjo.png" alt="Common Motions" width="373" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me explain how this works, suppose you press +, this would take you to the first non-blank character of the next line, but if you press 10+, it’ll take you to the first non-blank character of the 10th line from the current position.&lt;/p&gt;

&lt;p&gt;Let me give you some more examples to make things clear.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dW2EnZfi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ri9rgdt6w0iwvxvjeqca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dW2EnZfi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ri9rgdt6w0iwvxvjeqca.png" alt="Example Motions" width="426" height="134"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Putting It All Together
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[count][operator][text objects/ motions]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the template for using all the vim commands. Your imagination is your limit. Here is a list of commands you can look at.&lt;/p&gt;

&lt;p&gt;Here is the list of commands that I use the most:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M0sLuCaR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rrbfurq9ltjw0lcntahl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M0sLuCaR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rrbfurq9ltjw0lcntahl.png" alt="My most used commands" width="429" height="157"&gt;&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;This guide is just the beginning into the world of vim, but this guide here provides a basic understanding of how vim works, which is enough to get you excited about vim.&lt;/p&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=E-ZbrtoSuzw&amp;amp;t=876s&amp;amp;ab_channel=Leeren"&gt;YouTube&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>3 Terminal Commands to Increase Your Productivity</title>
      <dc:creator>Pankaj Gupta</dc:creator>
      <pubDate>Sun, 31 Dec 2023 01:44:37 +0000</pubDate>
      <link>https://dev.to/pankajgupta221b/3-terminal-commands-to-increase-your-productivity-57dm</link>
      <guid>https://dev.to/pankajgupta221b/3-terminal-commands-to-increase-your-productivity-57dm</guid>
      <description>&lt;p&gt;Here are a few important shortcuts that help me be more productive throughout the day at work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating aliases for commands.&lt;/li&gt;
&lt;li&gt;Using pbcopy.&lt;/li&gt;
&lt;li&gt;Using reverse search in the terminal.&lt;/li&gt;
&lt;li&gt;Bonus tricks and tips.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Alias for Commands
&lt;/h2&gt;

&lt;p&gt;Alias can be one of the most powerful tools in our hands, it provides us with the power to write our own shortcuts. Let’s see with an example what I mean.&lt;/p&gt;

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

&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"cd ~/Project/development"&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Whenever I type dev and hit enter it’ll run this command. This becomes very useful when navigating to different folders. We can run almost all the commands in the alias. Here is the list of some of my most-used commands:&lt;/p&gt;

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

&lt;span class="nb"&gt;alias&lt;/span&gt; ..&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"cd .."&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;gs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git status"&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;gp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git pull"&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;gb&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git branch"&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;ga&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git add ."&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;So, using these aliases, I save a lot of time during the day, to up a directory I type, instead of cd… I think the rest of them are self-explanatory. We can also use arguments with $1, $2, etc. for more extendability, like in this example:&lt;/p&gt;

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

&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;gc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git commit -m &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now, all I have to type is gc “Commit message” and it’ll commit my changes with the provided message. All you have to do is find your most-used commands and try to make them shorter using an alias to make yourself more productive.&lt;/p&gt;

&lt;p&gt;Now that we know what the aliases can do, let us see how we can set them. There are two ways in which we can achieve this, the first is temporary and can be set by running the command:&lt;/p&gt;

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

&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"cd ~/Project/development"&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This will work until the session is closed. The other way is to set these aliases permanently. For that, we need to set it up in our shell, I use Zsh, so I’ll be updating my ~/.zshrc file.&lt;/p&gt;

&lt;p&gt;If you are using Bash, use the ~/.bashrc file. Add the commands to the file and your file should look like this:&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%2Fsjvxp2o7i3t6o5v3jl36.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%2Fsjvxp2o7i3t6o5v3jl36.png" alt=".zshrc file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After making changes to this file, you need to run the command:&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;source&lt;/span&gt; ~/.zshrc


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

&lt;/div&gt;

&lt;p&gt;Then, all your aliases will be available for your use.&lt;/p&gt;




&lt;h2&gt;
  
  
  pbcopy
&lt;/h2&gt;

&lt;p&gt;This command is available on Mac and if you want to use it on Linux distributions, you can follow this guide.&lt;/p&gt;

&lt;p&gt;pbcopy is copy on steroids. You can use this command to copy the contents of a file to the clipboard. Let me give you an example. Suppose you have to copy your SSH identity to the clipboard, you can do it with this command:&lt;/p&gt;

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

pbcopy &amp;lt; ~/.ssh/id_rsa.pub


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

&lt;/div&gt;

&lt;p&gt;You can save your other passwords in different files and make use of this while logging in.&lt;/p&gt;

&lt;p&gt;Suppose you are using and accessing a remote server, and you have to provide the password, instead of opening the file, you can just pbcopy it to your clipboard and without all the hassle of opening and closing files, you’ll have the passwords.&lt;/p&gt;

&lt;p&gt;It becomes more useful when it is piped with other commands like grep. It’ll copy the grepped results to the clipboard. Let’s see with an example:&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;grep&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;keyword&amp;gt;"&lt;/span&gt; | pbcopy


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

&lt;/div&gt;

&lt;p&gt;I use this command when I am debugging the log files, and I provide a keyword to be searched for, like a timestamp, and all the lines are copied onto my clipboard.&lt;/p&gt;

&lt;p&gt;I can paste it in a file to see the required logs instead of the whole file. It can be even more useful if you use the tee command as a pipe to grep, it’ll write the results to a file.&lt;/p&gt;

&lt;p&gt;It has the following syntax:&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;grep&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;keyword&amp;gt;"&lt;/span&gt; | &lt;span class="nb"&gt;tee &lt;/span&gt;myfile.txt


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

&lt;/div&gt;




&lt;h2&gt;
  
  
  Using Reverse Search
&lt;/h2&gt;

&lt;p&gt;Reverse search is one of the coolest things available on the Unix system.&lt;/p&gt;

&lt;p&gt;Suppose you forget the full command and you only remember some parts, what you can do is you can go to the reverse search and type the words that you remember. Let’s see it with an example.&lt;/p&gt;

&lt;p&gt;I have to restart my server running in the staging environment, I only remember the staging keyword and forgot the rest of the command. So, I type ctrl + rto go into reverse-search mode and type:&lt;/p&gt;

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

&lt;span class="o"&gt;(&lt;/span&gt;reverse-i-search&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;stag&lt;span class="s1"&gt;': cd /home/ubuntu/server; pm2 stop app.js &amp;amp;&amp;amp; export NODE_ENV="staging" &amp;amp;&amp;amp; pm2 start app.js &amp;amp;&amp;amp; pm2 logs
```

It’ll remember the commands previously entered and finds the right match that you are looking for.

---

## Bonus Tricks and Tips

### cal
It prints the current month on the terminal. It has many different options available, which can be checked using man cal.


![Calendar View](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ronihzsjagme3dp5fifp.png)

### Encrypting a file using vim

You can encrypt a file using vim, just type :X. It’ll ask you to set a password which will look like this:


![Encrypting a file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4uunprvj2jm2do8azxe1.png)

When you access this file again, it’ll ask you for the password.


![Opening an encrypted file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ke8oweb76p36djzxf0kz.png)

---

## Conclusion

Please do mention your most used commands and add to the list.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>programming</category>
      <category>datascience</category>
      <category>vim</category>
    </item>
  </channel>
</rss>
