mongoose-qb
A powerful and flexible query builder for Mongoose that simplifies building complex queries with filtering, searching, sorting, field limiting, and pagination.
🚀 Installation
npm install mongoose-qb
or
yarn add mongoose-qb
🌟 Overview
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
📘 Core Concepts
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.
⚙️ Usage
✅ Option 1: Use the built-in useQuery
(with default config)
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;
};
🛠️ Option 2: Create a custom-configured query builder
Step 1: Generate a QueryBuilder
import { genQueryBuilder } from "mongoose-qb";
const QueryBuilder = genQueryBuilder({
defaultLimit: 10,
defaultPage: 1,
defaultSortField: "-createdAt",
});
🧠 mongoose-qb
automatically excludes common control keys like searchTerm
, sort
, fields
, page
, and limit
from filtering. You don’t need to configure that manually.
Step 2: Create a reusable query function
import { createUseQuery } from "mongoose-qb";
export const useQuery = createUseQuery(QueryBuilder);
Step 3: Use it in your service or controller
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
Options
genQueryBuilder({
defaultLimit?: number;
defaultPage?: number;
defaultSortField?: string;
});
🧠 Chainable Methods
.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 } |
📦 Return Format
{
meta: {
total: number;
limit: number;
page: number;
pages: number;
},
data: T[]
}
Example Response
{
"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."
}
]
}
🔍 Supported Query Parameters
searchTerm=...
sort=createdAt
or sort=-price
fields=title,location
page=2
limit=5
🧑💻 TypeScript Support
Built with full TypeScript support.
const result = await useQuery<ITour>(Tour.find(), query).resolver();
result.data[0].title;
🤝 Contributing
We welcome contributions!
- Fork this repo
- Create a feature branch
- Submit a pull request 🚀
📄 License
MIT License © 2025 DevAbabil
🧭 Vision
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.