A powerful and extensible query builder for Mongoose
Simplify complex query operations like filtering, searching, sorting, pagination and field projection — all from HTTP query parameters.
- Full-text search across specified fields
- Dynamic filtering with exact match
- Sorting by any model field
- Field limiting (projection)
- Pagination with meta info
- Population support (including nested paths)
- TypeScript support
- Built-in handler:
useQuery
- Optional factory:
createQuery
npm install mongoose-qb
# or
yarn add mongoose-qb
Build flexible and clean Mongoose queries from HTTP query parameters.
Example request:
GET /tours?search=sundarban&sort=-createdAt,price&d=title,price&page=2&limit=20
Parameter | Example | Description |
---|---|---|
Search | ?search=sundarban |
Searches across configured fields |
Filter | ?title=Beach Holiday |
Exact match filtering |
Sort | ?sort=-createdAt,price |
Sort with - prefix for descending |
Fields | ?fields=title,price |
Field projection |
Pagination | ?page=2&limit=20 |
Pagination control |
Supports flat and nested Mongoose populate
.
// useQuery option
populate: [
{ path: "author", select: "-__v -password" },
{ path: "comment", select: "-__v" },
{ path: "field.inner", select: "-__v -title" },
];
// useQuery option
excludes: ["password", "_id"];
import { useQuery } from "mongoose-qb";
export const retrievePosts = async (query: Record<string, string>) => {
/*
useQuery<T>(model, query, options)
*/
const post = await useQuery<IPost>(Post, query, {
fields: true,
filter: true,
sort: true,
paginate: true,
excludes: ["comments", "likes"],
search: ["title", "description", "slug"],
populate: [{ path: "author", select: "-__v" }],
});
return post; // returns { meta, data }
};
Create a custom instance in utils/useQuery.ts
:
import { createQuery } from "mongoose-qb";
export const useQuery = createQuery({
defaultLimit: 30,
defaultPage: 1,
defaultSortField: "-createdAt",
});
Then use it:
import { useQuery } from "@/utils/useQuery";
export const retrievePosts = async (query: Record<string, string>) => {
const post = await useQuery<IPost>(Post, query, {
search: ["title", "description", "slug"],
fields: true,
filter: true,
sort: true,
paginate: true,
/* ...more options */
});
return post; // returns { meta, data }
};
{
meta: {
total: number; // Total documents
page: number; // Current page
limit: number; // Items per page
totalPage: number; // Total pages
},
data: Array<T>; // Your documents
}
Option | Type | Description |
---|---|---|
search |
Array<string> |
Fields to search in |
fields |
boolean |
Enable field projection |
filter |
boolean |
Enable exact match filtering |
sort |
boolean |
Enable sorting |
paginate |
boolean |
Enable pagination |
populate |
Array<IQBPopulate> |
Population configuration |
excludes |
Array<keyof T> |
Excludes configuration |
MIT License © 2025 DevAbabil
mongoose-qb
aims to bring a clean, fluent, and highly customizable querying experience to Mongoose-based applications — reducing boilerplate and unlocking the full potential of query parameters.
Built with ❤️ by DevAbabil