Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/abejarano/ts-mongo-criteria/llms.txt

Use this file to discover all available pages before exploring further.

MongoCriteriaConverter bridges the library’s domain-level Criteria object and the raw query shape that the MongoDB Node.js driver expects. Call converter.convert(criteria) and you get back a MongoQuery you can feed directly into find, sort, skip, and limit calls — or let MongoRepository.list() do it for you automatically.

MongoQuery interface

convert() always returns an object that satisfies MongoQuery:
export interface MongoQuery {
  filter: MongoFilter
  sort:   MongoSort
  skip:   number
  limit:  number
}
filter
MongoFilter
The MongoDB filter document derived from the Criteria’s Filters. Each Filter in the criteria becomes a top-level key (or an $or array). When the criteria has no filters this is an empty object {}.
sort
{ [field: string]: 1 | -1 }
The sort specification. A value of 1 means ascending, -1 means descending. When no order is specified the default is { _id: -1 } (newest-first by insertion order). When the orderBy field is the string "id" it is automatically remapped to "_id" for MongoDB compatibility.
skip
number
The number of documents to skip, derived from the page offset. When no offset is provided (or the criteria has no limit) this is 0. For a page-based criteria constructed as new Criteria(filters, order, limit, page), skip is computed as (page - 1) * limit.
limit
number
The maximum number of documents to return. Maps directly to the limit value on the Criteria. 0 means no limit (the MongoDB driver returns all matching documents).

convert(criteria: Criteria): MongoQuery

The primary public method. Converts a fully-constructed Criteria into a MongoQuery.
const converter = new MongoCriteriaConverter()
const query: MongoQuery = converter.convert(criteria)

const results = await collection
  .find(query.filter)
  .sort(query.sort)
  .skip(query.skip)
  .limit(query.limit)
  .toArray()
Parameters
NameTypeDescription
criteriaCriteriaThe criteria object encapsulating filters, order, limit, and page.
Returns MongoQuery

Protected methods

These methods are protected so you can override them in a subclass for custom translation logic.

generateFilter(filters: Filters): MongoFilter

Iterates filters.filters and maps each Filter to a MongoDB filter fragment using the operator transformer registry. The fragments are merged with Object.assign so multiple filters on different fields are combined into a single flat object.
// Input  : Filters with [status = "active", age > 18]
// Output : { status: { $eq: "active" }, age: { $gt: "18" } }
Throws Error if an Operator value has no registered transformer.

generateSort(order: Order): MongoSort

Converts an Order value object into a MongoDB sort document. The orderBy field "id" is remapped to "_id".
// Order.asc("name")  → { name:  1 }
// Order.desc("id")   → { _id: -1 }

Default behaviors

ScenarioResulting value
Criteria has no filters (Filters.none())filter: {}
Criteria has no order (Order.none())sort: { _id: -1 }
Criteria has no offset / pageskip: 0
Criteria has no limitlimit: 0 (no limit)

Operator mapping

Every Operator enum value maps to a MongoDB query operator:
OperatorMongoDB operatorNotes
EQUAL (=)$eqStrict equality
NOT_EQUAL (!=)$neInequality
GT (>)$gtGreater than
LT (<)$ltLess than
GTE (>=)$gteGreater than or equal
LTE (<=)$lteLess than or equal
CONTAINS$regexSubstring / pattern match
NOT_CONTAINS$not: { $regex }Negated pattern match
BETWEEN$gte + $lteRequires { start, end }, { startDate, endDate }, or { from, to } value
IN$inRequires an array of primitive values
NOT_IN$ninRequires an array of primitive values
OR$orRequires an array of OrCondition objects

Example

import {
  MongoCriteriaConverter,
  Criteria,
  Filters,
  Order,
  Operator,
  OrderTypes,
  MongoQuery,
} from "@abejarano/ts-mongodb-criteria"

const converter = new MongoCriteriaConverter()

// Build a Criteria: status = "active", age > 18
// sorted by createdAt DESC, page 2, 10 per page
const criteria = new Criteria(
  Filters.fromValues([
    new Map([["field", "status"],  ["operator", Operator.EQUAL], ["value", "active"]]),
    new Map([["field", "age"],     ["operator", Operator.GT],    ["value", 18]]),
  ]),
  Order.fromValues("createdAt", OrderTypes.DESC),
  10, // limit
  2   // page (offset = (2-1)*10 = 10)
)

const query: MongoQuery = converter.convert(criteria)

console.log(query)
// {
//   filter: { status: { $eq: "active" }, age: { $gt: 18 } },
//   sort:   { createdAt: -1 },
//   skip:   10,
//   limit:  10,
// }

BETWEEN date range

The BETWEEN operator accepts any of three value shapes: { start, end }, { startDate, endDate }, or { from, to }. All three are normalised to { start, end } internally before producing the $gte/$lte filter.
const start = new Date("2024-01-01T00:00:00.000Z")
const end   = new Date("2024-01-31T23:59:59.999Z")

const criteria = new Criteria(
  Filters.fromValues([
    new Map([
      ["field",    "createdAt"],
      ["operator", Operator.BETWEEN],
      ["value",    { start, end }],
    ]),
  ]),
  Order.none()
)

const query = converter.convert(criteria)
// query.filter → { createdAt: { $gte: <start>, $lte: <end> } }

// Equivalent alternatives:
// { startDate: start, endDate: end }
// { from: start, to: end }

OR across multiple fields

import { OrCondition } from "@abejarano/ts-mongodb-criteria"

const orConditions: OrCondition[] = [
  { field: "name",  operator: Operator.CONTAINS, value: "alice" },
  { field: "email", operator: Operator.CONTAINS, value: "alice" },
]

const criteria = new Criteria(
  Filters.fromValues([
    new Map([
      ["field",    "search"],   // field name is ignored for OR
      ["operator", Operator.OR],
      ["value",    orConditions],
    ]),
  ]),
  Order.none()
)

const query = converter.convert(criteria)
// query.filter → { $or: [{ name: { $regex: "alice" } }, { email: { $regex: "alice" } }] }

Subclassing

You can extend MongoCriteriaConverter to alter how filters or sorts are generated — for example to support case-insensitive regex or a custom sort field alias:
import { MongoCriteriaConverter, Filters, Order } from "@abejarano/ts-mongodb-criteria"

class CaseInsensitiveConverter extends MongoCriteriaConverter {
  protected override generateFilter(filters: Filters) {
    const base = super.generateFilter(filters)
    // post-process: wrap all $regex values with the 'i' option
    for (const [key, op] of Object.entries(base) as any) {
      if (op?.$regex) {
        (base as any)[key] = { $regex: op.$regex, $options: "i" }
      }
    }
    return base
  }
}
Pass your custom converter into a subclass of MongoRepository by overriding criteriaConverter if needed, or use it standalone for query building.

Build docs developers (and LLMs) love