Documentation

MongoDB operators

The operators supported by repository find and dynamic queries, with examples.

The data layer accepts standard MongoDB query operators in any place that takes a filter or query document — POST /repository/find/{datatype}, all /dynamic-query/* verbs, audience segments, automation conditions, and rule engine evaluations. This page is the reference.

Field paths point into data. Write data.email, data.address.city, data.tags — never the bare field name.

Comparison

FieldTypeDescription
$eqany

Equal. { "data.status": { "$eq": "active" } } — equivalent to { "data.status": "active" }.

$neany

Not equal. { "data.country": { "$ne": "US" } }.

$gtnumber | string | date

Greater than. { "data.score": { "$gt": 70 } }.

$gtenumber | string | date

Greater than or equal. { "data.stock": { "$gte": 1 } }.

$ltnumber | string | date

Less than.

$ltenumber | string | date

Less than or equal. { "data.price": { "$lte": 50 } }.

Set membership

FieldTypeDescription
$inany[]

Field equals one of. { "data.tag": { "$in": ["vip", "newsletter"] } }. For arrays, true if any array element matches any value.

$ninany[]

Field equals none of. { "data.status": { "$nin": ["deleted", "archived"] } }.

Existence and type

FieldTypeDescription
$existsboolean

true matches documents where the field is present (any value, including null). false matches missing only.

$typestring | number

Match by BSON type — string, number, bool, date, array, object, null.

Strings

FieldTypeDescription
$regexstring

Regex match. Pair with $options: "i" for case-insensitive: { "data.name": { "$regex": "^john", "$options": "i" } }. Escape user input — these run on the server.

$optionsstring

Regex flags: i (insensitive), m (multiline), s (dotall), x (extended).

Don't use $regex for prefix search at scale

For "starts-with" filters on indexed fields, prefer the keyword-search endpoint (/repository/search/{datatype}) — it uses the search index and is orders of magnitude faster on large collections.

Logical

FieldTypeDescription
$andobject[]

All clauses must match. Implicit when you list multiple fields at the top level. Use explicit $and only when the same field appears twice: { "$and": [{"data.score": {"$gt": 50}}, {"data.score": {"$lt": 90}}] }.

$orobject[]

Any clause matches. { "$or": [{"data.status": "open"}, {"data.priority": "urgent"}] }.

$norobject[]

None of the clauses match.

$notobject

Negate the inner expression.

Arrays

FieldTypeDescription
$allany[]

Field array contains all values. { "data.tags": { "$all": ["vip", "active"] } }.

$sizenumber

Array has exact length.

$elemMatchobject

At least one array element matches the inner filter as a whole. Use this when filtering arrays of objects: { "data.lineItems": { "$elemMatch": { "sku": "X1", "qty": { "$gte": 2 } } } }.

Update operators

These appear in the update body of updateOne / updateMany, never in filter.

FieldTypeDescription
$setobject

Set fields. { "$set": { "data.status": "closed" } }.

$unsetobject

Remove fields. { "$unset": { "data.legacyId": "" } }.

$incobject

Increment numeric fields. { "$inc": { "data.viewCount": 1 } }.

$pushobject

Append to array. { "$push": { "data.tags": "newsletter" } }. Combine with $each to append many.

$pullobject

Remove matching elements from an array.

$addToSetobject

$push that skips duplicates.

Worked examples

Active leads scored 70+ in the last 30 days

{
  "collection": "lead",
  "filter": {
    "data.status": "active",
    "data.score": { "$gte": 70 },
    "modifydate": { "$gte": "2026-03-26T00:00:00Z" }
  }
}

Customers with at least one tag from a list, no opt-out

{
  "collection": "contact",
  "filter": {
    "data.tags": { "$in": ["promo-q2", "newsletter"] },
    "data.optedOut": { "$ne": true }
  }
}

Orders that contain a specific SKU at qty >= 2

{
  "collection": "order",
  "filter": {
    "data.lineItems": {
      "$elemMatch": { "sku": "MUG-XL", "qty": { "$gte": 2 } }
    }
  }
}

Products with stock OR explicitly marked as backorderable

{
  "collection": "product",
  "filter": {
    "$or": [
      { "data.stock": { "$gt": 0 } },
      { "data.backorderable": true }
    ]
  }
}

Edge cases

  • null vs missing: { "data.x": null } matches BOTH null values and missing fields. To distinguish, combine with $exists.
  • Comparing dates: send ISO-8601 strings. The provider parses them when comparing against a Date-typed field.
  • Array fields with scalar comparison: { "data.tags": "vip" } matches if the array contains "vip". This is convenient but easy to mistake for "equals the literal array".
  • Nested arrays beyond one level: dot paths stop working once you cross two array boundaries. Use $elemMatch or an aggregation $unwind.
  • Case sensitivity: string operators are case-sensitive by default. Use $regex with $options: "i", or normalize on write.
  • Reserved system fields: pk, sk, version, state, createdate, modifydate live at the top level of the wrapper, not under data. Filter them as { "state": "published" }, not { "data.state": "published" }.

For the broader query API see Dynamic queries and Repository CRUD.