A powerful and flexible query builder for Mongoose that simplifies building complex queries with filtering, searching, sorting, field limiting, and pagination.
npm install mongoose-qb
or
yarn add mongoose-qb
mongoose-qb
helps you create reusable query builder hooks/functions that wrap around Mongoose queries, making it easy to apply common query patterns such as:
- 🔍 Searching (across multiple fields)
- 🎯 Filtering
- 🔃 Sorting
- 📦 Field selection
- 📚 Pagination
-
genQueryBuilder(options)
: Generate a customized query builder instance. -
createUseQuery(QueryBuilder)
: Create a reusable query function based on your builder. -
Chainable API: Use
.search()
,.filter()
,.sort()
,.fields()
,.paginate()
. -
.resolver()
: Executes the query and returns data with metadata.
import { useQuery } from "mongoose-qb";
export const retrieveAllTour = async (query: Record<string, string>) => {
const result = await useQuery<ITour>(Tour.find(), query)
.search(["title", "description", "location"])
.filter()
.sort()
.fields()
.paginate()
.resolver();
return result;
};
import { genQueryBuilder } from "mongoose-qb";
const QueryBuilder = genQueryBuilder({
defaultLimit: 10,
defaultPage: 1,
defaultSortField: "-createdAt",
});
🧠
mongoose-qb
automatically excludes common control keys likesearchTerm
,sort
,fields
,page
, andlimit
from filtering. You don’t need to configure that manually.
import { createUseQuery } from "mongoose-qb";
export const useQuery = createUseQuery(QueryBuilder);
import { useQuery } from "./your-query-file";
export const retrieveAllTour = async (query: Record<string, string>) => {
const result = await useQuery<ITour>(Tour.find(), query)
.search(["title", "description", "location"])
.filter()
.sort()
.fields()
.paginate()
.resolver();
return result;
};
genQueryBuilder({
defaultLimit?: number; // Default limit per page (default: 10)
defaultPage?: number; // Default starting page (default: 1)
defaultSortField?: string; // Default sort key (e.g. "-createdAt")
});
Method | Description |
---|---|
.search(fields: string[]) |
Performs text search using the searchTerm query param |
.filter() |
Filters documents based on query keys (ignoring control keys) |
.sort() |
Sorts using the sort query param or default |
.fields() |
Selects fields using fields=title,description
|
.paginate() |
Uses page and limit to paginate |
.resolver() |
Executes and returns { meta, data }
|
{
meta: {
total: number; // Total matching documents
limit: number; // Documents per page
page: number; // Current page
pages: number; // Total pages
},
data: T[] // Results (typed)
}
{
"meta": {
"total": 42,
"limit": 10,
"page": 2,
"pages": 5
},
"data": [
{
"_id": "66a12c...",
"title": "Explore Sundarbans",
"location": "Khulna",
"description": "A 3-day adventurous tour into the world's largest mangrove forest."
}
]
}
searchTerm=...
-
sort=createdAt
orsort=-price
fields=title,location
page=2
limit=5
Built with full TypeScript support.
const result = await useQuery<ITour>(Tour.find(), query).resolver();
result.data[0].title; // ✅ type-safe
We welcome contributions!
- Fork this repo
- Create a feature branch
- Submit a pull request 🚀
MIT License © 2025 DevAbabil
mongoose-qb
aims to bring a clean, fluent, and highly customizable querying experience for Mongoose developers by reducing API boilerplate and making powerful features easy to use.
Built with 🖤 by DevAbabil — designed to be simple, powerful, and lovable.