mongo-qb
v0.0.1
Published
MongoDB Query Builder
Maintainers
Readme
mongo-qb
An elegant and intuitive query builder for MongoDB with Mongoose, just like modern ORMs.
Installation
npm install mongo-qbBasic Usage
import { query } from "mongo-qb";
// or
import { QueryBuilder } from "mongo-qb";
// With model name
const users = query("users").where({ age: 18 }).get();
// With Mongoose model
const User = mongoose.model("User");
const adults = query(User).whereGreater({ age: 18 }).get();Filtering Methods
where(...objects)
Filter with conditions (AND within one object, OR across multiple objects)
// AND: name="john" AND age=25
query("users").where({ name: "john", age: 25 });
// OR: name="john" OR age=25
query("users").where({ name: "john" }, { age: 25 });whereNot(...objects)
Filter with negation
query("users").whereNot({ status: "banned" });whereIn(objects) / whereNotIn(objects)
Filter with values in/not in an array
query("users").whereIn({ role: ["admin", "moderator"] });
query("users").whereNotIn({ age: [12, 15, 17] });Numeric Comparisons
query("products").whereGreater({ price: 100 }); // price > 100
query("products").whereLess({ stock: 10 }); // stock < 10
query("products").whereGreaterEq({ rating: 4 }); // rating >= 4
query("products").whereLessEq({ discount: 50 }); // discount <= 50
query("products").whereBetween({ price: [10, 100] }); // 10 <= price <= 100
query("products").whereNotBetween({ age: [18, 65] }); // age < 18 OR age > 65Text Search
// Case-insensitive search
query("users").whereLike({ name: "john" }); // /john/i
query("users").whereLike({ email: /.*@gmail\.com$/ });
query("users").whereNotLike({ name: "admin" });
// Alias
query("users").whereMatch({ bio: "developer" });Field Existence
query("users").whereExists("email", "phone");
query("users").whereNotExists("deletedAt");Raw Queries
query("users").whereRaw({ $and: [{ age: { $gt: 18 } }, { status: "active" }] });Sorting and Pagination
// Sorting
query("users").sort("name", "asc"); // or 'a'
query("users").orderBy("age", "desc"); // or 'd'
// Pagination
query("users").limit(10).skip(20);
query("users").paginate(3, 10); // page 3, 10 per pageField Selection
query("users").select("name", "email", "age");Query Combination
const admins = query("users").where({ role: "admin" });
const moderators = query("users").where({ role: "moderator" });
// OR
const staff = query("users").or(admins, moderators);
// AND
const activeAdmins = query("users")
.where({ role: "admin" })
.and(query().where({ status: "active" }));Aggregations
// Group by category and calculate statistics
query("products")
.group("category")
.sum("price", "totalPrice")
.avg("rating", "avgRating")
.max("stock", "maxStock")
.min("discount", "minDiscount")
.get();
// Count documents
const count = await query("users").where({ age: 18 }).count();Data Retrieval
// All results
const users = await query("users").where({ age: 18 }).get();
const users = await query("users").find(); // alias
// First result
const user = await query("users").first();
const user = await query("users").getOne(); // with limit(1)
const user = await query("users").findOne(); // alias
// First N results
const topUsers = await query("users").orderBy("score", "desc").take(5);Update Operations
update(data, all?)
Standard update ($set)
query("users").where({ age: 17 }).update({ status: "minor" });
query("users").where({ age: 18 }).update({ status: "adult" }, true); // allupdateInc(data, all?)
Increment values ($inc)
query("users").where({ id: 123 }).updateInc({ score: 10, level: 1 });updateMul(data, all?)
Multiply values ($mul)
query("products").updateMul({ price: 1.1 }, true); // +10% on all pricesupdateRename(oldField, newField, all?)
Rename a field ($rename)
query("users").updateRename("age", "years", true);Array Operations
// Add an element ($push)
query("users").updatePush({ badges: "veteran" });
// Add without duplicates ($addToSet)
query("users").updateAdd({ badges: "unique-badge" });
// Remove an element ($pull)
query("users").updatePull({ badges: "newbie" });
// Remove at index
query("products").updateRemoveAt("images", 0, true);
// Remove first/last element ($pop)
query("products").updatePop("prices", -1); // first
query("products").updatePop("prices", 1); // last (default)updateUnset(fields, all?)
Remove fields ($unset)
query("users").updateUnset(["tempField", "oldData"], true);
query("users").updateUnset("deprecatedField");updateRaw(data, all?)
Raw update
query("users").updateRaw({
$set: { status: "active" },
$inc: { loginCount: 1 },
});Deletion
// Delete multiple documents (safe by default)
await query("users").where({ status: "inactive" }).delete();
// Delete ALL documents (unsafe)
await query("temp").delete(false);
// Delete a single document
await query("users").where({ id: 123 }).deleteOne();Debugging and Inspection
const q = query("users").where({ age: 18 }).sort("name");
// Display query
console.log(q.queryToString());
// Display aggregation pipeline
console.log(q.toString());
// Debug to console
q.debug();
// Human-readable explanation
console.log(q.explain());
q.explain(true); // with automatic logging
// JSON format
console.log(q.toJson());
// SQL format (approximate)
console.log(q.toSQL());Cloning
const baseQuery = query("users").where({ status: "active" });
// Full clone
const admins = baseQuery.clone().where({ role: "admin" });
// Clone without aggregations
const simpleClone = baseQuery.clone(true);Useful Properties
const q = query("users");
q.model; // Mongoose model
q.collection; // MongoDB collection
q.collectionName; // Collection name
q.schema; // Model schema
q.query; // MongoDB query object
q.pipeline; // Aggregation pipelineAdvanced Examples
Conditions Based Query Building
const isProduction = process.env.NODE_ENV === "production";
const adultOnly = await getUserPreference("adultOnly"); ;
const q = query("users");
if (isProduction) q.whereNot({ type: "dev" });
if (adultOnly) q.whereGreaterEq({ age: 18 });
const users = await q.get(); // query depends on conditionsComplex Search with Pagination
const results = await query("products")
.where({ category: "electronics" })
.whereGreater({ rating: 4 })
.whereBetween({ price: [100, 500] })
.whereLike({ name: "phone" })
.orderBy("price", "asc")
.paginate(2, 20)
.select("name", "price", "rating")
.get();Grouped Statistics
const stats = await query("orders")
.where({ status: "completed" })
.group("product_id")
.sum("amount", "totalRevenue")
.avg("amount", "avgOrderValue")
.count()
.get();Conditional Update
await query("users")
.whereBetween({ age: [13, 17] })
.update({ category: "teen" }, true);
await query("products")
.whereLess({ stock: 10 })
.updatePush({ tags: "low-stock" }, true);API Reference
Constructor
new QueryBuilder(modelOrName: string | mongoose.Model)Query Methods
where(...objects)- Add AND/OR conditionswhereNot(...objects)- Negation filterwhereIn(objects)- Match values in arraywhereNotIn(objects)- Match values not in arraywhereGreater(objects)- Greater than comparisonwhereLess(objects)- Less than comparisonwhereGreaterEq(objects)- Greater than or equalwhereLessEq(objects)- Less than or equalwhereBetween(objects)- Between two valueswhereNotBetween(objects)- Not between two valueswhereLike(objects)- Pattern matching (regex)whereNotLike(objects)- Negative pattern matchingwhereMatch(objects)- Alias for whereLikewhereExists(...fields)- Field existswhereNotExists(...fields)- Field doesn't existwhereRaw(condition)- Raw MongoDB condition
Sorting & Pagination
sort(field, direction?)- Sort resultsorderBy(field, direction?)- Alias for sortlimit(n)- Limit resultsskip(n)- Skip resultspaginate(page?, perPage?)- Paginate results
Field Selection Methods
select(...fields)- Select specific fields
Query Combination Methods
or(...builders)- Combine with ORand(...builders)- Combine with AND
Aggregations Methods
group(stageName?)- Group aggregationssum(field, alias?)- Sum aggregationavg(field, alias?)- Average aggregationmax(field, alias?)- Maximum aggregationmin(field, alias?)- Minimum aggregationcount()- Count documents
Retrieval
get()- Get all matching documentsfind()- Alias for getfirst()- Get first resultgetOne()- Get one with limit(1)findOne()- Alias for getOnetake(n)- Take N results
Update Operations Methods
update(data, all?)- Standard updateupdateRaw(data, all?)- Raw updateupdateInc(data, all?)- IncrementupdateMul(data, all?)- MultiplyupdateRename(oldField, newField, all?)- Rename fieldupdatePush(data, all?)- Push to arrayupdateAdd(data, all?)- Add to set (no duplicates)updatePull(data, all?)- Pull from arrayupdateUnset(fields, all?)- Remove fieldsupdateRemoveAt(field, index, all?)- Remove at indexupdatePop(field, direction?, all?)- Pop from array
Deletion Methods
delete(safe?)- Delete matching documentsdeleteOne()- Delete first matching document
Utilities
clone(queryOnly?)- Clone builderdebug()- Log pipelineexplain(log?)- Get readable explanationtoJson()- Convert to JSONtoSQL()- Convert to SQL (approximate)toString()- Pipeline as stringqueryToString()- Query as string
License
MIT
mongo-qb - Simplicity and power for your MongoDB queries
By happydev
