How to use LIMIT and OFFSET in Sequelize.js

Updated: December 29, 2023 By: Guest Contributor Post a comment

Sequelize is a promise-based Node.js ORM for Postgres, MySQL, MariaDB, SQLite, and Microsoft SQL Server. It features solid transaction support, relations, eager and lazy loading, read replication and more. When it comes to handling large datasets, it’s crucial to know how to use LIMIT and OFFSET clauses for pagination. This tutorial will cover the basics of implementing pagination using LIMIT and OFFSET in Sequelize.js, complete with code examples.

Understanding LIMIT and OFFSET

The LIMIT clause in SQL is used to specify the maximum number of records to return, while OFFSET specifies the number of records to skip before starting to return records. They are instrumental in implementing pagination, which is vital for improving performance and user experience in applications that handle large quantities of data.

Example of basic Sequelize LIMIT and OFFSET:

const { Op } = require('sequelize');
const users = await User.findAll({
  limit: 10, // Limit the number of users returned
  offset: 20 // Skip the first 20 users
});

Implementing Pagination

Pagination is widely used in applications that display large sets of data, such as social media platforms, e-commerce sites, and search engines. It helps in reducing the load on the database and enhancing the user experience by loading data incrementally.

Here’s how to implement basic pagination in Sequelize:

const getPage = async (page, pageSize) => {
  const limit = pageSize;
  const offset = (page - 1) * pageSize;
  return await User.findAll({ limit, offset });
};

// Usage:
const usersPage1 = await getPage(1, 10); // First page, 10 users per page
const usersPage2 = await getPage(2, 10); // Second page

Advanced Usage

In more advanced scenarios, you might want to implement complex filtering along with pagination. Sequelize offers the ability to combine LIMIT and OFFSET with where clauses, order, include for relations, and more.

Example with filtering and sorting:

const getPageWithFilter = async (filterOptions, page, pageSize) => {
  const { search, order } = filterOptions;
  const limit = pageSize;
  const offset = (page - 1) * pageSize;
  return await User.findAll({
    where: {
      username: {
        [Op.like]: `%${search}%`
      }
    },
    limit,
    offset,
    order: [[order.field, order.direction]]
  });
};

// Usage:
const filterOptions = {
  search: 'john',
  order: { field: 'createdAt', direction: 'DESC' }
};

const filteredUsersPage1 = await getPageWithFilter(filterOptions, 1, 10);

Handling Offset and Limit Dynamically

To handle offset and limit dynamically, you can create an API endpoint that accepts page and pageSize as query parameters. You can then call this API with different parameters to fetch different pages of data.

app.get('/users', async (req, res) => {
  const { page, pageSize } = req.query;
  const users = await getPage(page || 1, pageSize || 10);
  res.json(users);
});

Conclusion

In conclusion, using LIMIT and OFFSET in Sequelize.js can significantly improve the performance of your application when dealing with large datasets. While it may seem complex at first, understanding and implementing pagination with Sequelize is straightforward once you grasp the basics. This tutorial provided a starting point for using these clauses in Sequelize with real-world examples. Remember that proper implementation of pagination is crucial for optimizing database queries and providing a better user experience.