<?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>Forem: pvivekdev (Vivekananthan P) </title>
    <description>The latest articles on Forem by pvivekdev (Vivekananthan P)  (@vivekdev).</description>
    <link>https://forem.com/vivekdev</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%2F952653%2F2f37b9eb-7a12-44d8-a5b1-354a0114a941.png</url>
      <title>Forem: pvivekdev (Vivekananthan P) </title>
      <link>https://forem.com/vivekdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/vivekdev"/>
    <language>en</language>
    <item>
      <title>Decorators in Typescript</title>
      <dc:creator>pvivekdev (Vivekananthan P) </dc:creator>
      <pubDate>Wed, 04 Jan 2023 00:51:16 +0000</pubDate>
      <link>https://forem.com/vivekdev/decorators-in-typescript-2kcc</link>
      <guid>https://forem.com/vivekdev/decorators-in-typescript-2kcc</guid>
      <description>&lt;p&gt;Decorators are similar to annotations in JAVA or the attributes in C#. They provide additional definitions for a class, property, or function. Decorators are proposed as a part of ECMAScript 7. Decorators are useful to inject additional capabilities into existing definitions without the need to rewrite or duplicate the existing code.&lt;/p&gt;

&lt;p&gt;To use decorator we need to enable “experimentalDecorators” to true in tsconfig.json. Otherwise, we will be prompted with the below compile time error when compiling typescript tsc &lt;/p&gt;

&lt;p&gt;error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set the ‘experimentalDecorators’ option in your ‘tsconfig’ or ‘jsconfig’ to remove this warning.&lt;/p&gt;

&lt;p&gt;I came across this when developing microservice using Nestjs and it becomes really important to understand them as it is widely used across in Nestjs ecosystem. e.g. @UseGuards in Nestjs is an example of a method | class decorator.&lt;/p&gt;

&lt;p&gt;Decorators can be viewed as simple functions with input parameters that provide definitions of a class, property, or function at runtime. Note the usage of @.&lt;/p&gt;

&lt;p&gt;Decorators are called during the definition stage and not in the instance creation stage. To understand better let's look at this example&lt;/p&gt;

&lt;p&gt;`function simpleDecorator(target:Function)&lt;br&gt;
{&lt;br&gt;
   console.log("I am from simple decorator");&lt;br&gt;
}&lt;br&gt;
@simpleDecorator&lt;br&gt;
export class ClassType&lt;br&gt;
{&lt;br&gt;
  constructor()&lt;br&gt;
  {&lt;br&gt;
    console.log("I am from ctor");&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
let instance = new ClassType();&lt;/p&gt;

&lt;p&gt;output: &lt;br&gt;
I am from simple decorator&lt;br&gt;
I am from ctor`&lt;/p&gt;

&lt;p&gt;“I am from simple decorator” is printed in the console before “I am from ctor” We can see that decorators are invoked before instance creations. in fact, if we create multiple instances of classType we will see decorators are called only once when the classType is defined.&lt;/p&gt;

&lt;p&gt;Ok, But why we are having the parameter of decorator as a function why not another type in the above example? That is because the Class in TS is a Function in Javascript. If we don’t have the type as the function and have it as string type then we will get an error “Argument of type ‘type ClassType’ is not assignable to parameter of type ‘String’.”&lt;/p&gt;

&lt;p&gt;Can we have multiple decorators applied to a class, property, or function? Yes.&lt;/p&gt;

&lt;p&gt;What if we have to pass parameters to the decorator? For this, we have to use a decorator factory. The decorator factory returns a decorator function e.g.&lt;/p&gt;

&lt;p&gt;//Decorator factory return a decorator function &lt;br&gt;
function decoratorFactory(paramters: any[])&lt;br&gt;
{&lt;br&gt;
  return function(ctor:Function)&lt;br&gt;
  {&lt;br&gt;
  console.log(&lt;code&gt;Data passed onto decorator:${paramters}&lt;/code&gt;);&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
@decoratorFactory(["param 1", "param 2", "param n"])&lt;br&gt;
export class TargetClass{&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Types of Decorators&lt;/p&gt;

&lt;p&gt;Class decorators.&lt;/p&gt;

&lt;p&gt;Method decorators.&lt;/p&gt;

&lt;p&gt;Property decorators.&lt;/p&gt;

&lt;p&gt;Parameter decorators.&lt;/p&gt;

&lt;p&gt;Class decorator&lt;/p&gt;

&lt;p&gt;All the above examples we have seen so far are of class decorators. With class-level decorators, we can inject property through prototypes e.g.&lt;/p&gt;

&lt;p&gt;function Component(targetClass:Function)&lt;br&gt;
{&lt;br&gt;
  //Injecting porperty via decorator.&lt;br&gt;
  targetClass.prototype.FrmDecoraator = "prototype property set by decorator";&lt;br&gt;
  console.log(targetClass.name);&lt;/p&gt;

&lt;p&gt;//Accessing the name property of the target class Function.&lt;br&gt;
  console.log((targetClass).StaticProperty); &lt;br&gt;
}&lt;br&gt;
//class decorator&lt;br&gt;
@Component&lt;br&gt;
export class TargetClass&lt;br&gt;
{ &lt;br&gt;
  static StaticProperty:string ="static property";&lt;br&gt;
  constructor()&lt;br&gt;
  {&lt;br&gt;
    console.log("I am from ctor");&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
let instanceOfTargetClass= new TargetClass();&lt;br&gt;
//Injected prototype from decorator function into TargetClass&lt;br&gt;
console.log((instanceOfTargetClass).FrmDecoraator);&lt;br&gt;
Property Decorators :&lt;/p&gt;

&lt;p&gt;Property decorators are applied to the properties within a class. it is a function that accepts the prototype of the class and the property key as its input parameters. In the below e.g. we can access the static property values but not the instance property value as decorators are created before instance creation.&lt;/p&gt;

&lt;p&gt;function propetryDecorators(target:any,propertyKey:string)&lt;br&gt;
{&lt;br&gt;
    console.log(target.constructor.name);&lt;br&gt;
    console.log(&lt;code&gt;property Key name :${propertyKey}&lt;/code&gt;);&lt;br&gt;
    /*Property value is undefined for non static property&lt;br&gt;
     as it is not yet initialized, but we can access the value of static property here. */&lt;br&gt;
    console.log(&lt;code&gt;property value :${target[propertyKey]}&lt;/code&gt;);&lt;br&gt;
}&lt;br&gt;
export class propetryDecoratorExample&lt;br&gt;
{&lt;br&gt;
 @propetryDecorators&lt;br&gt;
  name:string  = "property inside class"&lt;/p&gt;

&lt;p&gt;@propetryDecorators&lt;br&gt;
  static staticProperty:string ="Static property";&lt;br&gt;
}&lt;br&gt;
let instance = new propetryDecoratorExample();&lt;br&gt;
Method decorators:&lt;/p&gt;

&lt;p&gt;As the name suggests these decorators are applied to the method in the class. Method decorators are functions with three parameters (class prototype, method name, and the optional param descriptor about the method). e.g. AuthGaurd() in Nest is an example of a method decorator. AuthGaurd is triggered first before the method invocation.&lt;/p&gt;

&lt;p&gt;Parameter decorators&lt;/p&gt;

&lt;p&gt;To decorate the parameters of a method. .e.g &lt;a class="mentioned-user" href="https://dev.to/body"&gt;@body&lt;/a&gt;(), &lt;a class="mentioned-user" href="https://dev.to/param"&gt;@param&lt;/a&gt;() in Nest js routes are of parameter decorator type. Parameter decorators can be used to check if the parameter is part of the method. To probe further on the parameter say the type of the parameter we need to install a third-party tool npm install reflect-metadata --save-dev and enable "emitDecoratorMetadata": true in tsconfig.json file.&lt;/p&gt;

&lt;p&gt;import 'reflect-metadata';&lt;/p&gt;

&lt;p&gt;function paramDecorator(target:any,methodName:string, parameterIndex:number)&lt;br&gt;
{&lt;br&gt;
console.log(&lt;code&gt;target: ${target.constructor.name}&lt;/code&gt;);&lt;br&gt;
console.log(&lt;code&gt;methodName : ${methodName}&lt;/code&gt;);&lt;br&gt;
console.log(&lt;code&gt;parameterIndex : ${parameterIndex}&lt;/code&gt;);&lt;/p&gt;

&lt;p&gt;//using reflection to probe more on the parameter.&lt;br&gt;
let designType = Reflect.getMetadata(&lt;br&gt;
    "design:type", target, methodName);&lt;br&gt;
    console.log(&lt;code&gt;designType: ${designType}&lt;/code&gt;);&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let designParamTypes = Reflect.getMetadata(
"design:paramtypes", target, methodName);
console.log(`paramtypes : ${designParamTypes}`);
if(designParamTypes !== String)
{
   console.log("not string");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
class ClassType&lt;br&gt;
{&lt;br&gt;
 Method(@paramDecorator param:number ,   nonParameterDecorator:string)&lt;br&gt;
 {}&lt;br&gt;
}&lt;br&gt;
After enabling the "emitDecoratorMetadata": true, Generated .js file will have info about the __decorate __metadata.&lt;/p&gt;

&lt;p&gt;__decorate([&lt;br&gt;
    __param(0, paramDecorator),&lt;br&gt;
    __metadata("design:type", Function),&lt;br&gt;
    __metadata("design:paramtypes", [Number, String]),&lt;br&gt;
    __metadata("design:returntype", void 0)&lt;br&gt;
], ClassType.prototype, "Method", null);&lt;/p&gt;

&lt;p&gt;References for further reading on this topic&lt;/p&gt;

&lt;p&gt;Packt Mastering Type script second edition by Mr. Nathan Rozentals&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.nestjs.com/custom-decorators" rel="noopener noreferrer"&gt;https://docs.nestjs.com/custom-decorators&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://javascript.plainenglish.io/master-the-typescript-keyof-type-operator-bf7f18865a8b" rel="noopener noreferrer"&gt;https://javascript.plainenglish.io/master-the-typescript-keyof-type-operator-bf7f18865a8b&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you for reading. Until we meet again I Wish you the very best.&lt;br&gt;
Vivek&lt;/p&gt;

</description>
      <category>emptystring</category>
    </item>
    <item>
      <title>Indexing on MongoDB Collection - Part 1</title>
      <dc:creator>pvivekdev (Vivekananthan P) </dc:creator>
      <pubDate>Tue, 01 Nov 2022 06:56:11 +0000</pubDate>
      <link>https://forem.com/vivekdev/indexing-on-mongodb-collection-part-1-5aoh</link>
      <guid>https://forem.com/vivekdev/indexing-on-mongodb-collection-part-1-5aoh</guid>
      <description>&lt;p&gt;Indexing makes the read queries faster. We can apply indexing on any of the fields in the document including the embedded fields. When documents are indexed MongoDB will search with filtered offset first rather than doing COLLSCAN ( column-span) on all documents and then applying filter criteria to it.&lt;/p&gt;

&lt;p&gt;Let us understand this by creating an index to the existing collection and comparing the query execution stats before and after applying the indexing.&lt;/p&gt;

&lt;p&gt;By the way, I am using Mongo DB Atlas Free cluster for this walk-through. Mongo Altas is a cloud-based solution to host and manage NoSQL data and it also provides a free cluster for learning purposes with one click option to load sample data set into your free cluster. I liked it :)&lt;/p&gt;

&lt;p&gt;To connect to the Atlas cluster I am using VS Code extension “MongoDB VS Code”. There are other ways as well such as using mongo shell, mongo Atlas UI. Please refer to the link below &lt;a href="https://www.mongodb.com/docs/atlas/getting-started/"&gt;https://www.mongodb.com/docs/atlas/getting-started/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am using the “sample_airbnb” data set loaded into my Atlas account and querying them using MongoDB for VS code extension.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Please note In case the image screenshot are not clearly visible kindly open them in a new tab or click on the image description to open in new tab.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qtIfK6Bf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q36woi1qu2u92j1j1m67.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qtIfK6Bf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q36woi1qu2u92j1j1m67.png" alt="Fetch query on property type without having any index on “listingAndReview” collection" width="720" height="144"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In above query , I am executing find query on collection: “listingAndReviews” where the property_type is house. I am also using regex to fetch result ignoring case sensitive and the explain(‘executionStats’) function to get query plan.&lt;/p&gt;

&lt;p&gt;In the presence of indexing, the winningPlan section will have inputStage.stage as IXSCAN&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8NA21FqA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bupgu8jyhv58ojlb0n65.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8NA21FqA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bupgu8jyhv58ojlb0n65.png" alt="execution stats for “listingandReview” with Indexing." width="509" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I removed all pre-created indexes from the “listingAndReviews” collection and re-execute the same query. We can see the winningPlan.stage as “COLLSPAN” and the executionStats.executionTimeMillis as 118. The totalDocsExamined as 5555 to find the 606 records matching our search criteria.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XeSPuqas--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w7elp3qjg6jmqb0zqygh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XeSPuqas--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w7elp3qjg6jmqb0zqygh.png" alt="execution stats without applying indexing to “listingAndReviews” collection" width="509" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let us create an index on the field “property_ type” to fetch results faster.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xr324JUB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jlfiq73bkz7kzp8252s4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xr324JUB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jlfiq73bkz7kzp8252s4.png" alt="&amp;lt;br&amp;gt;
Create a Single index on property type field" width="720" height="49"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--omahasm1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h42dd9fi6phltgjo568p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--omahasm1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h42dd9fi6phltgjo568p.png" alt="execution stats for fetch query after applying indexing on “property_type”" width="648" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To define an index , We need to understand the queries required and the volume of read and write operations that going to be performed on the collection. Indexing will have some amount of taxation on the write operation that’s the reason we shouldn’t apply indexing to all the document fields.&lt;/p&gt;

&lt;p&gt;Note* Creating indices on the fields where the fetch query will return close to all documents from the collection will not help and in fact will slow the query execution. Create index based on the query use case such that the query result should return only the limited fetch result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compound Index
&lt;/h2&gt;

&lt;p&gt;The above examples are on the single index field. There is another type of index called “Compound Index” where two or more fields are considered for indexing in the same order they were added.&lt;/p&gt;

&lt;p&gt;If we have two fields added as compound indexes the precedence will start from left to right. For example, let us create a compound index on “listingAndReviews” collection using “beds and address.country_code ” (embedded document) fields.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mi0jJpdd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f275ms0ubm3vhrwe7gxv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mi0jJpdd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f275ms0ubm3vhrwe7gxv.png" alt="Compound index using no of beds and address country code" width="720" height="49"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The order of the fields is important here and precedence is from left to right. i.e. the field beds get first priority and followed by address.country_code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m30YPSOY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qu0t173dxkyvwti929mb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m30YPSOY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qu0t173dxkyvwti929mb.png" alt="Image description" width="720" height="46"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the above query, Even though we use two filters in the find query to fetch results having beds count as 1 and can accommodate 4 people. here “accommodates” field is not part of our index keys. Mongo DB performs IXSCAN i.e. index scan and not the COLLSPAN column spanning all the documents within the collection because we have the “beds” added as part of our key index and the precedence is from left to right.&lt;/p&gt;

&lt;p&gt;In case we query only with accommodates fields, Mongo DB performs COLLSPAN and examines all the documents of a total count of 5555&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eEK40gDt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xl15pwhhpsh00otrljbn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eEK40gDt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xl15pwhhpsh00otrljbn.png" alt="Image description" width="720" height="486"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Rules for defining an index
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Use the ESR (Equality, Sort, Range) Rule&lt;/li&gt;
&lt;li&gt;Create Indexes to Support Your Queries&lt;/li&gt;
&lt;li&gt;Use Indexes to Sort Query Results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We need index not only for fetching the results quickly but also to use sorting. In case of non indexed document, Mongo DB has limit of 32 MB in memory and this will time out in case sorting (Default in- memory sorting) of huge millions of document without indexing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure Indexes Fit in RAM&lt;/li&gt;
&lt;li&gt;Create Queries that Ensure Selectivity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the next part of this series, we will drill down to other types of indexes and the best practices to follow while creating indexes.&lt;/p&gt;

&lt;p&gt;To be continued.&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>indexing</category>
      <category>nosql</category>
      <category>database</category>
    </item>
  </channel>
</rss>
