Rabbit mongoose, part one: getting data faster

Mongoose makes developers life easier and is easy to use. But the examples we’ve all seen is not the fastest way of using it. Here is some tips than can help you when dealing with huge amount of data.

♻ Foreword

I’m  a fan of Promises, so I gonna use them in my examples. However the same can be achieved using callback.

 

♻  Plain javascript object

By default, mongoose returns its own objects and not the javascript objects returned by mongo’s driver. Mongoose objects have useful methods, like save

  • This is handy…when we need those methods
  • Transforming plain javascript object to mongoose magic objects has a performance cost…even when we need not those extra methods.

  The conclusion is obvious: avoid mongoose objects whenever they are not needed.

You probably already know but in case you don’t, lot of models’ methods return query objects. The query objects have the lean option to prevent transformation to mangoose magical objects. Using lean is straightforward:

MyModel.find (…).lean ().then (…);

 

♻ Get only what we need: fields list

By default, mongoose returns the full documents, with all fields. But what if we need only some fields ? All finds methods provide fields filter. If want name and age fields only I write:

MyModel.find(…,’name age’).then (…)

The above example select only name and age fields. The opposite exists also:

MyModel.find(…, ‘-name -age’).then (…)

This gets all fields but name and age.  Note that you can exclude a field by default when declaring the model: Selection in schema type. This is handy for security: if password or any sensitive informations are stored, unelected them by default ensures that they will be used only when needed, thus reducing risk of disclosure.

 

♻ Get only what we need: array elements

With projection operator or element match, query results  contains only first element matching the query. This is useful when we need one subdocument stored in an array. Without them, a query returns the full array elements.

Let’s say that we want the name and professional adresses of our contacts, we have to write a query which select the contacts with address type pro and returns expected fields:

ContactsModel.find ({adresses.type: ‘pro’ }, {_id: 1, name:1, addresses. $: 1}).then (…)

address.$ is the mean to get only the selected address (the same can be done using element match) .

 

💡 Have you notice the way fields are selected in the above example ? Here I use an object and note a string like in the previous chapter.  ‘_id name address. $’ and {_id: 1, name:1, addresses. $: 1} has both the same meaning but the object approach is the only one used by mongo native driver.  When we use the string approach, Mongoose generates the matching objects. The object approach, if verbose, is slightly faster.

 


 

This conclue my tips about mongoose optimization. I hope you find them useful. Notice that this post focus only on coding, you can find tips about mongoose configuration in mongoose doc.

 

  🙋 See you and have a nice code

 

Advertisements