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.

ts-mongo-criteria ships with twelve operators that cover the full range of MongoDB query conditions. Each operator is represented as a value of the Operator enum and is applied through a Filter built from a plain Map. The MongoCriteriaConverter translates your Criteria into a ready-to-use MongoDB filter object, so your domain layer never touches raw $eq, $gte, or $or syntax.

Operators reference

Enum memberString valueMongoDB equivalentDescription
Operator.EQUAL"="{ field: { $eq: value } }Exact match
Operator.NOT_EQUAL"!="{ field: { $ne: value } }Excludes matching documents
Operator.GT">"{ field: { $gt: value } }Greater than
Operator.GTE">="{ field: { $gte: value } }Greater than or equal
Operator.LT"<"{ field: { $lt: value } }Less than
Operator.LTE"<="{ field: { $lte: value } }Less than or equal
Operator.BETWEEN"BETWEEN"{ field: { $gte: start, $lte: end } }Inclusive range
Operator.CONTAINS"CONTAINS"{ field: { $regex: value } }Regex substring match
Operator.NOT_CONTAINS"NOT_CONTAINS"{ field: { $not: { $regex: value } } }Negated regex match
Operator.IN"IN"{ field: { $in: [...] } }Matches any value in array
Operator.NOT_IN"NOT_IN"{ field: { $nin: [...] } }Excludes all values in array
Operator.OR"OR"{ $or: [...] }Logical OR across multiple conditions

Equality operators

EQUAL

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

const filter = new Map<string, any>([
  ["field", "status"],
  ["operator", Operator.EQUAL],
  ["value", "active"],
])

const criteria = new Criteria(Filters.fromValues([filter]), Order.none())
Generated MongoDB filter:
{ "status": { "$eq": "active" } }

NOT_EQUAL

const filter = new Map<string, any>([
  ["field", "role"],
  ["operator", Operator.NOT_EQUAL],
  ["value", "banned"],
])

const criteria = new Criteria(Filters.fromValues([filter]), Order.none())
Generated MongoDB filter:
{ "role": { "$ne": "banned" } }

Comparison operators

GT (greater than)

const filter = new Map<string, any>([
  ["field", "age"],
  ["operator", Operator.GT],
  ["value", 18],
])
{ "age": { "$gt": 18 } }

GTE (greater than or equal)

const filter = new Map<string, any>([
  ["field", "score"],
  ["operator", Operator.GTE],
  ["value", 90],
])
{ "score": { "$gte": 90 } }

LT (less than)

const filter = new Map<string, any>([
  ["field", "price"],
  ["operator", Operator.LT],
  ["value", 100],
])
{ "price": { "$lt": 100 } }

LTE (less than or equal)

const filter = new Map<string, any>([
  ["field", "stock"],
  ["operator", Operator.LTE],
  ["value", 5],
])
{ "stock": { "$lte": 5 } }

Range operator: BETWEEN

The BETWEEN operator accepts three different object shapes. All three are normalised internally to a { start, end } pair before being converted to { $gte, $lte }.
The value passed to a BETWEEN filter must be one of the three recognised shapes below. Passing a primitive or an array will throw an error at converter runtime.
Shape 1 — { start, end }
const filter = new Map<string, any>([
  ["field", "age"],
  ["operator", Operator.BETWEEN],
  ["value", { start: 18, end: 65 }],
])
{ "age": { "$gte": 18, "$lte": 65 } }
Shape 2 — { startDate, endDate }
const filter = new Map<string, any>([
  ["field", "createdAt"],
  ["operator", Operator.BETWEEN],
  ["value", {
    startDate: new Date("2024-01-01"),
    endDate:   new Date("2024-12-31"),
  }],
])
{ "createdAt": { "$gte": "2024-01-01T00:00:00.000Z", "$lte": "2024-12-31T00:00:00.000Z" } }
Shape 3 — { from, to }
const filter = new Map<string, any>([
  ["field", "price"],
  ["operator", Operator.BETWEEN],
  ["value", { from: 10, to: 50 }],
])
{ "price": { "$gte": 10, "$lte": 50 } }

Text operators

CONTAINS

Uses MongoDB $regex for a case-sensitive substring search. Pass a regex-safe string as the value.
const filter = new Map<string, any>([
  ["field", "name"],
  ["operator", Operator.CONTAINS],
  ["value", "Smith"],
])
{ "name": { "$regex": "Smith" } }

NOT_CONTAINS

const filter = new Map<string, any>([
  ["field", "email"],
  ["operator", Operator.NOT_CONTAINS],
  ["value", "@spam.com"],
])
{ "email": { "$not": { "$regex": "@spam.com" } } }

List operators

IN

const filter = new Map<string, any>([
  ["field", "country"],
  ["operator", Operator.IN],
  ["value", ["US", "CA", "MX"]],
])
{ "country": { "$in": ["US", "CA", "MX"] } }

NOT_IN

const filter = new Map<string, any>([
  ["field", "status"],
  ["operator", Operator.NOT_IN],
  ["value", ["deleted", "banned"]],
])
{ "status": { "$nin": ["deleted", "banned"] } }

Logical operator: OR

The OR operator maps across multiple fields or conditions and emits a top-level MongoDB $or array. The value must be an array of OrCondition objects, each with field, operator, and value keys.
The OR operator requires an OrCondition[] array as its value — not a primitive, a plain string, or a BetweenValue. Passing any other type will throw "OR operator requires an array of OrCondition objects" at query-conversion time.
import { OrCondition } from "@abejarano/ts-mongodb-criteria"

const orConditions: OrCondition[] = [
  { field: "firstName", operator: Operator.CONTAINS, value: "John" },
  { field: "lastName",  operator: Operator.CONTAINS, value: "John" },
  { field: "email",     operator: Operator.CONTAINS, value: "john" },
]

const filter = new Map<string, any>([
  ["field", "search"],   // field name is required by the Map shape but ignored for $or
  ["operator", Operator.OR],
  ["value", orConditions],
])

const criteria = new Criteria(Filters.fromValues([filter]), Order.none())
Generated MongoDB filter:
{
  "$or": [
    { "firstName": { "$regex": "John" } },
    { "lastName":  { "$regex": "John" } },
    { "email":     { "$regex": "john" } }
  ]
}
Supported operators inside an OrCondition: EQUAL, NOT_EQUAL, GT, GTE, LT, LTE, CONTAINS, NOT_CONTAINS.

Combining multiple filters

All filters passed in the same Filters.fromValues() call are merged with an implicit AND (MongoDB assigns all fields in the same filter document):
const criteria = new Criteria(
  Filters.fromValues([
    new Map([["field", "status"],  ["operator", Operator.EQUAL],   ["value", "active"]]),
    new Map([["field", "age"],     ["operator", Operator.GTE],     ["value", 18]]),
    new Map([["field", "country"], ["operator", Operator.IN],      ["value", ["US", "CA"]]]),
  ]),
  Order.asc("name"),
  20, // limit
  1   // page
)
Generated MongoDB filter:
{
  "status":  { "$eq": "active" },
  "age":     { "$gte": 18 },
  "country": { "$in": ["US", "CA"] }
}

Build docs developers (and LLMs) love