@feedmepos/mongoquery
v1.0.0
Published
MongoDB query library for TypeScript with CJS and ESM support
Downloads
118
Readme
@feedmepos/mongoquery
MongoDB query library for TypeScript with CJS and ESM support.
Installation
pnpm add @feedmepos/mongoquery
# or
npm install @feedmepos/mongoquery
# or
yarn add @feedmepos/mongoqueryFeatures
- 🎯 Full TypeScript support with type definitions
- 📦 Multiple module formats: CJS and ESM
- 🔍 MongoDB query parsing and validation
- 🔗 Fluent query builder with method chaining
- ⚡ Query evaluation against JSON documents
- 🛡️ Type-safe query operations
- 🪶 Lightweight with no dependencies
- ⚡ Built with tsup for optimal bundle size
Usage
Query Runner
The query runner evaluates MongoDB queries against JSON documents and returns true or false.
import { MongoQueryRunner, createRunner } from '@feedmepos/mongoquery';
const document = {
name: 'John Doe',
age: 25,
email: '[email protected]',
status: 'active',
tags: ['javascript', 'typescript']
};
// Using the class
const runner = new MongoQueryRunner();
// Simple equality
const matches1 = runner.evaluate({ status: 'active' }, document); // true
// Comparison operators
const matches2 = runner.evaluate({ age: { $gte: 18 } }, document); // true
// Complex query
const matches3 = runner.evaluate({
status: 'active',
age: { $gte: 18, $lte: 30 },
email: { $exists: true }
}, document); // true
// Using the factory function
const strictRunner = createRunner({ strict: true });
const matches4 = strictRunner.evaluate({ age: { $gt: 20 } }, document); // trueQuery Builder (Fluent API)
The query builder provides a fluent API for constructing MongoDB queries with method chaining.
import { MongoQueryBuilder, createBuilder } from '@feedmepos/mongoquery';
// Using the class
const builder = new MongoQueryBuilder();
const query = builder
.gte('age', 18)
.lte('age', 65)
.in('status', ['active', 'pending'])
.exists('email', true)
.build();
// Using the factory function
const query2 = createBuilder()
.where('name', 'John')
.gt('score', 80)
.build();Query Parser
The parser validates and processes MongoDB query objects.
import { MongoQueryParser, createParser } from '@feedmepos/mongoquery';
// Using the class
const parser = new MongoQueryParser();
const query = parser.parse({ age: { $gt: 18 } });
// Using the factory function
const strictParser = createParser({ strict: true });
const validatedQuery = strictParser.parse({ name: { $eq: 'John' } });ES Modules (ESM)
import { MongoQueryBuilder, MongoQueryParser } from '@feedmepos/mongoquery';
const builder = new MongoQueryBuilder();
const query = builder.gte('age', 18).build();
const parser = new MongoQueryParser();
const parsedQuery = parser.parse(query);CommonJS (CJS)
const { MongoQueryBuilder, MongoQueryParser } = require('@feedmepos/mongoquery');
const builder = new MongoQueryBuilder();
const query = builder.gte('age', 21).build();API
MongoQueryRunner
The query runner for evaluating MongoDB queries against JSON documents.
Constructor
new MongoQueryRunner(options?: ParserOptions)Options:
strict(boolean): Enable strict operator validation. Default:false
Methods
evaluate(query: MongoQuery, document: any): boolean
Evaluates a MongoDB query against a document and returns true if the document matches the query.
const runner = new MongoQueryRunner();
const document = { name: 'John', age: 25, status: 'active' };
// Simple equality
const result1 = runner.evaluate({ status: 'active' }, document); // true
// Complex query
const result2 = runner.evaluate({
age: { $gte: 18 },
status: { $in: ['active', 'pending'] }
}, document); // trueSupported Operations
The runner supports all standard MongoDB query operators:
Comparison Operators: $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin
Logical Operators: $and, $or, $not, $nor
Element Operators: $exists, $type
Array Operators: $all, $elemMatch, $size
Evaluation Operators: $regex, $mod
Nested Fields: Supports dot notation (e.g., address.city)
createRunner(options?: ParserOptions): MongoQueryRunner
Factory function to create a runner instance.
const runner = createRunner({ strict: true });
const matches = runner.evaluate({ age: { $gt: 18 } }, { age: 25 }); // trueMongoQueryBuilder
The fluent query builder for constructing MongoDB queries using method chaining.
Constructor
new MongoQueryBuilder()Methods
All methods return this for method chaining, except build() which returns the final query.
Basic Methods
where(field: string, value: any): this- Set a field to a specific valuebuild(): MongoQuery- Build and return the final query objectreset(): this- Reset the builder to start a new query
Comparison Operators
eq(field: string, value: any): this- Equal to ($eq)ne(field: string, value: any): this- Not equal to ($ne)gt(field: string, value: number | string | Date): this- Greater than ($gt)gte(field: string, value: number | string | Date): this- Greater than or equal ($gte)lt(field: string, value: number | string | Date): this- Less than ($lt)lte(field: string, value: number | string | Date): this- Less than or equal ($lte)in(field: string, values: any[]): this- In array ($in)nin(field: string, values: any[]): this- Not in array ($nin)
Logical Operators
and(...conditions: MongoQuery[]): this- Logical AND ($and)or(...conditions: MongoQuery[]): this- Logical OR ($or)nor(...conditions: MongoQuery[]): this- Logical NOR ($nor)not(field: string, condition: any): this- Logical NOT ($not)
Element Operators
exists(field: string, exists?: boolean): this- Field exists ($exists)type(field: string, type: number | string): this- Field type ($type)
Evaluation Operators
regex(field: string, pattern: string | RegExp, options?: string): this- Regular expression ($regex)mod(field: string, divisor: number, remainder: number): this- Modulo operation ($mod)text(search: string, options?: object): this- Text search ($text)where_js(code: string | Function): this- JavaScript expression ($where)
Array Operators
all(field: string, values: any[]): this- All elements match ($all)elemMatch(field: string, condition: MongoQuery): this- Element match ($elemMatch)size(field: string, size: number): this- Array size ($size)
Example Usage
import { MongoQueryBuilder } from '@feedmepos/mongoquery';
const query = new MongoQueryBuilder()
.gte('age', 18)
.lte('age', 65)
.in('status', ['active', 'pending'])
.exists('email', true)
.regex('name', '^John', 'i')
.build();
console.log(query);
// {
// age: { $gte: 18, $lte: 65 },
// status: { $in: ['active', 'pending'] },
// email: { $exists: true },
// name: { $regex: '^John', $options: 'i' }
// }createBuilder(): MongoQueryBuilder
Factory function to create a new query builder instance.
import { createBuilder } from '@feedmepos/mongoquery';
const query = createBuilder()
.where('category', 'electronics')
.gt('price', 100)
.build();MongoQueryParser
The main query parser class.
Constructor
new MongoQueryParser(options?: ParserOptions)Options:
strict(boolean): Enable strict operator validation. Default:false
Methods
parse(query: MongoQuery): MongoQuery
Parses and validates a MongoDB query.
const parser = new MongoQueryParser();
const query = parser.parse({
age: { $gte: 18, $lt: 65 },
status: 'active'
});isValid(query: MongoQuery): boolean
Checks if a query is valid without throwing errors.
const parser = new MongoQueryParser();
const isValid = parser.isValid({ age: { $gt: 18 } }); // truecreateParser(options?: ParserOptions): MongoQueryParser
Factory function to create a parser instance.
const parser = createParser({ strict: true });Supported Operators
Comparison Operators
$eq- Equal to$ne- Not equal to$gt- Greater than$gte- Greater than or equal to$lt- Less than$lte- Less than or equal to$in- In array$nin- Not in array
Logical Operators
$and- Logical AND$or- Logical OR$not- Logical NOT$nor- Logical NOR
Element Operators
$exists- Field exists$type- Field type
Evaluation Operators
$regex- Regular expression$mod- Modulo operation$text- Text search$where- JavaScript expression
Array Operators
$all- All elements match$elemMatch- Element match$size- Array size
TypeScript Types
The package exports the following TypeScript types:
import type {
MongoQuery,
ParserOptions,
MongoOperator,
ComparisonOperator,
LogicalOperator,
ElementOperator,
EvaluationOperator,
ArrayOperator,
FieldCondition
} from '@feedmepos/mongoquery';Examples
Query Runner Examples
Basic Matching
import { MongoQueryRunner } from '@feedmepos/mongoquery';
const runner = new MongoQueryRunner();
const user = {
name: 'John Doe',
age: 25,
status: 'active'
};
// Equality
runner.evaluate({ status: 'active' }, user); // true
runner.evaluate({ status: 'inactive' }, user); // false
// Comparison
runner.evaluate({ age: { $gte: 18 } }, user); // true
runner.evaluate({ age: { $lt: 20 } }, user); // false
// Multiple conditions (implicit AND)
runner.evaluate({
status: 'active',
age: { $gte: 18 }
}, user); // trueLogical Operators
const runner = new MongoQueryRunner();
const user = { age: 25, status: 'active' };
// OR condition
runner.evaluate({
$or: [
{ age: { $lt: 18 } },
{ status: 'inactive' }
]
}, user); // false
runner.evaluate({
$or: [
{ age: { $gte: 18 } },
{ status: 'inactive' }
]
}, user); // true
// AND condition
runner.evaluate({
$and: [
{ age: { $gte: 18 } },
{ status: 'active' }
]
}, user); // trueArray Operations
const runner = new MongoQueryRunner();
const user = {
name: 'John',
tags: ['javascript', 'typescript', 'nodejs']
};
// Check if field contains any of the values
runner.evaluate({ tags: { $in: ['javascript', 'python'] } }, user); // true
// Check if field contains all values
runner.evaluate({ tags: { $all: ['javascript', 'typescript'] } }, user); // true
runner.evaluate({ tags: { $all: ['javascript', 'python'] } }, user); // false
// Check array size
runner.evaluate({ tags: { $size: 3 } }, user); // true
runner.evaluate({ tags: { $size: 2 } }, user); // false
// Element match on array of objects
const product = {
reviews: [
{ rating: 5, comment: 'Great!' },
{ rating: 4, comment: 'Good' }
]
};
runner.evaluate({
reviews: { $elemMatch: { rating: { $gte: 4 } } }
}, product); // trueNested Fields
const runner = new MongoQueryRunner();
const user = {
name: 'John',
address: {
city: 'New York',
country: 'USA'
}
};
// Dot notation for nested fields
runner.evaluate({ 'address.city': 'New York' }, user); // true
runner.evaluate({ 'address.country': 'UK' }, user); // falseRegular Expressions
const runner = new MongoQueryRunner();
const user = { name: 'John Doe', email: '[email protected]' };
// Pattern matching
runner.evaluate({ name: { $regex: '^John' } }, user); // true
runner.evaluate({ email: { $regex: '@example\\.com$' } }, user); // trueCombining Builder and Runner
import { MongoQueryBuilder, MongoQueryRunner } from '@feedmepos/mongoquery';
// Build a query
const query = new MongoQueryBuilder()
.gte('age', 18)
.lte('age', 65)
.in('status', ['active', 'pending'])
.exists('email', true)
.build();
// Evaluate against documents
const runner = new MongoQueryRunner();
const users = [
{ name: 'John', age: 25, status: 'active', email: '[email protected]' },
{ name: 'Jane', age: 17, status: 'active', email: '[email protected]' },
{ name: 'Bob', age: 35, status: 'inactive' }
];
const matchingUsers = users.filter(user => runner.evaluate(query, user));
// Result: [{ name: 'John', age: 25, status: 'active', email: '[email protected]' }]Query Builder Examples
Basic Queries
import { MongoQueryBuilder } from '@feedmepos/mongoquery';
// Simple field matching
const query1 = new MongoQueryBuilder()
.where('name', 'John')
.where('age', 25)
.build();
// Result: { name: 'John', age: 25 }
// Range queries
const query2 = new MongoQueryBuilder()
.gte('age', 18)
.lte('age', 65)
.build();
// Result: { age: { $gte: 18, $lte: 65 } }Logical Operators
import { createBuilder } from '@feedmepos/mongoquery';
// OR conditions
const query = createBuilder()
.or(
{ age: { $lt: 18 } },
{ status: 'inactive' }
)
.build();
// Result: { $or: [{ age: { $lt: 18 } }, { status: 'inactive' }] }
// AND conditions
const query2 = createBuilder()
.and(
{ age: { $gte: 18 } },
{ status: 'active' }
)
.build();
// Result: { $and: [{ age: { $gte: 18 } }, { status: 'active' }] }Array Operators
import { createBuilder } from '@feedmepos/mongoquery';
const query = createBuilder()
.in('status', ['active', 'pending'])
.nin('role', ['admin'])
.size('tags', 3)
.build();
// Result: {
// status: { $in: ['active', 'pending'] },
// role: { $nin: ['admin'] },
// tags: { $size: 3 }
// }Complex Query
import { MongoQueryBuilder } from '@feedmepos/mongoquery';
const query = new MongoQueryBuilder()
.gte('age', 18)
.lte('age', 65)
.in('department', ['sales', 'marketing'])
.exists('email', true)
.ne('status', 'inactive')
.regex('name', '^John', 'i')
.build();
// Result: {
// age: { $gte: 18, $lte: 65 },
// department: { $in: ['sales', 'marketing'] },
// email: { $exists: true },
// status: { $ne: 'inactive' },
// name: { $regex: '^John', $options: 'i' }
// }Builder Reuse
import { createBuilder } from '@feedmepos/mongoquery';
const builder = createBuilder();
// First query
const query1 = builder
.where('category', 'electronics')
.gte('price', 100)
.build();
// Reset and build a different query
const query2 = builder
.reset()
.where('category', 'books')
.lte('price', 50)
.build();Parser Examples
Basic Query
import { MongoQueryParser } from '@feedmepos/mongoquery';
const parser = new MongoQueryParser();
const query = parser.parse({
name: 'John',
age: { $gte: 18 }
});Complex Query
import { createParser } from '@feedmepos/mongoquery';
const parser = createParser();
const query = parser.parse({
$and: [
{ age: { $gte: 18 } },
{ status: { $in: ['active', 'pending'] } }
]
});Strict Mode
import { MongoQueryParser } from '@feedmepos/mongoquery';
const parser = new MongoQueryParser({ strict: true });
// This will throw an error for unknown operators
try {
parser.parse({ field: { $unknownOp: 'value' } });
} catch (error) {
console.error(error.message); // "Unknown operator: $unknownOp"
}Building
pnpm run buildThis will generate:
dist/index.js- CommonJS moduledist/index.mjs- ES moduledist/index.d.ts- TypeScript type definitions (CJS)dist/index.d.mts- TypeScript type definitions (ESM)
Development
This package uses:
- pnpm as the package manager
- tsup for building and bundling
- TypeScript for type safety
License
MIT
