Skip to content

patrickcavli/mongoose-query-methods-cheatsheet

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 

Repository files navigation

Cheatsheet for Mongoose Query Methods

A cheatsheet of methods you can use to implement common patterns in mongoose data-fetching(eg pagination, filtering etc).

Screenshot-2021-09-22-at-17-39-15

Base Example

We'll work with a couple of queries which have not been resolved. Since each method returns the overall instance, we can chain methods

const todosQuery = Todo.find({});
const userQuery = User.find({});

Filtering By Value

Using the where() method in conjugation with some other methods, based on value we can filter out certain results.

The following methods are usually used with the where() method:

  • equals() - equal to
userQuery.where('age').equals(13); // results where user age is 18
  • gt() - greater than
userQuery.where('age').equals(13); // results where user age is more than 18
  • lt() - less than
userQuery.where('age').equals(13); // results where user age is less than 18
  • gte() - greater than or equal to
userQuery.where('age').gte(13); // results where user age is greater than or equal to 18
  • lte() - less than or equal to
userQuery.where('age').lte(18); // results where user age is less than or equal to 18
  • mod() - reminder
userQuery.where('age').mod([2, 1]); // all users where add is odd
  • ne() - not equal to
userQuery.where('age').ne(13); // results where age is not 13
  • size() - size of array
userQuery.where('projects').size(); // 3
  • regex() - use regex
userQuery.where('name').regex(/abc/i); // results where the name matches the pattern
  • slice() - JavaScript slice on the array of results
// projects is an array
userQuery.where('projects').slice(2); // results after doing the slice on each result
  • all() - all elements in the argument array is present
// projects is an array
userQuery.where('projects').all(['p1', 'p2', 'p3']); // results where the field has all the specified elements 

Sorting

sort()

The field name is the key, and the value states whether it's ascending or descending. There are different ways to implement this:

// -1 or 1
todosQuery.sort({ title: -1, description: 1 });

// 'ascending' or 'descending'
todosQuery.sort({ title: 'descending', description: 'ascending' });

// 'asc' or 'desc'
todosQuery.sort({ title: 'desc', description: 'asc' });

// shorthand - title is ascending and description is descending
todosQuery.sort('title -description');

Pagination

We can use a combination of limit and skip to implement pagination easily. Before that, let's look at how these two methods work.

limit()

todosQuery.limit(100);

skip()

This will skip the first x results of the find query.

todosQuery.skip(20);

Combining To Implement Pagination

Let's say that we are on page 2 and each page contains 10 results. We'll create a variable called page which is 2 and number which is 10.

So, we'll skip the first (page - 1) * number which will send the results 11 and above.

const page = 2;
const number = 10;

todosQuery.skip((page - 1) * number);

Until now, we've skipped the first 10 results, but we still show all of remaining results. Therefore, let's use the limit() method to limit the number of results.

const page = 2;
const number = 10;

// skip = 2-1 * 10 = first 10 results
// limit = 2 * 10 = first 20 results
// the results are limited to the first 11 to 20 results
todosQuery.skip((page - 1) * number).limit(page * 10);

Performance

explain()

This method returns execution stats instead of the data. It can be useful when comparing different approaches and analyzing which one is more performative.

const stats = await todosQuery.explain();

lean()

Lean removes all the getters, setters and the virtuals from the document that is returned by mongoose. The object returned is a plain JavaScript object and not a mongoose query compared to other query methods.

const user = await userQuery.lean();

Chaining further query methods will not work as the mongoose query is not returned, the result is. It's like calling the exec() method.


#### cursor() Cursors are the native way mongodb navigates through the database. With mongoose, an array is returned as a result of `find()` but the native driver returns a `Cursor`.

Mongoose allows us to get the data in the form a cursor/stream because it may be more performant in some cases.

// There are 2 ways to use a cursor. First, as a stream:
Thing.
  find({ name: /^hello/ }).
  cursor().
  on('data', function(doc) { console.log(doc); }).
  on('end', function() { console.log('Done!'); });

// Or you can use `.next()` to manually get the next doc in the stream.
// `.next()` returns a promise, so you can use promises or callbacks.
const cursor = Thing.find({ name: /^hello/ }).cursor();
cursor.next(function(error, doc) {
  console.log(doc);
});

// Because `.next()` returns a promise, you can use co
// to easily iterate through all documents without loading them
// all into memory.
const cursor = Thing.find({ name: /^hello/ }).cursor();
for (let doc = await cursor.next(); doc != null; doc = await cursor.next()) {
  console.log(doc);
}

About

A cheatsheet for mongodb query methods

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published