Skip to content

Filter Operators ​

Filter operators allow you to query and match documents using conditions and comparisons. They are used in database operations to specify which documents to retrieve, update, count, delete, or archive.

Operators Quick Reference ​

Comparison Operators:

OperatorTypeDescription
$eqComparisonEqual to (can be omitted)
$neComparisonNot equal to
$gtComparisonGreater than
$gteComparisonGreater than or equal
$ltComparisonLess than
$lteComparisonLess than or equal

Array Operators:

OperatorTypeDescription
$inArrayField value in array
$ninArrayField value not in array
$includesArrayArray field includes value
$nincludesArrayArray field doesn't include value
$allArrayArray field contains all values
$anyArrayArray field contains any value
$noneArrayArray field contains none

Range Operators:

OperatorTypeDescription
$betweenRangeValue between range (inclusive)

Logical Operators:

OperatorTypeDescription
$andLogicalImplicit - all conditions must match
$orLogicalAt least one condition group must match
$norLogicalNo condition groups may match

Overview ​

Filter Operators - Powerful query operators for matching documents based on field values. Used in read and write operations to specify which documents should be affected by the operation.

Where filters are used:

  • db.find - Query documents
  • db.count - Count matching documents
  • db.update - Update matching documents
  • db.upsert - Update or insert based on match
  • db.delete - Delete matching documents
  • db.archive - Archive matching documents

Filter structure:

json
{
  "op": "db.find",
  "collection": "users",
  "filter": {
    "age:$gte": 18,
    "status": "active"
  }
}

Logical Operators ​

Logical operators allow you to combine multiple filter conditions using AND, OR, and NOR logic.

Supported Logical Operators ​

OperatorTypeDescription
$andLogicalImplicit - all conditions must match (default)
$orLogicalAt least one condition group must match
$norLogicalNo condition groups may match

General Rules ​

  1. A filter object is either:

    • A field-condition map (implicit $and), or
    • A logical operator object ($or, $nor)
  2. Do NOT mix logical operators and field keys at the same level

  3. Logical operators must be top-level or nested under another logical operator

  4. $or and $nor require arrays


$and (Implicit) ​

The default behavior when multiple field conditions exist. All conditions must match.

Implicit AND:

json
{
  "age:$gte": 18,
  "status": "active",
  "country": "US"
}

Semantics:

age >= 18 AND status == "active" AND country == "US"

Example:

json
{
  "op": "db.find",
  "collection": "users",
  "filter": {
    "age:$gte": 18,
    "status": "active",
    "subscription:$ne": "cancelled"
  }
}

All three conditions must be true for a document to match.


$or ​

Logical OR between condition groups. At least one group must match.

Syntax:

json
{
  "$or": [
    { "condition1": "value1" },
    { "condition2": "value2" }
  ]
}
  • Value must be an array
  • Each array item must be an object
  • Each object is an AND group

Example:

json
{
  "op": "db.find",
  "collection": "users",
  "filter": {
    "$or": [
      { "status": "active" },
      { "role": "admin" }
    ]
  }
}

Semantics:

status == "active" OR role == "admin"

Matches users who are either active OR admins (or both).

Complex OR example:

json
{
  "op": "db.find",
  "collection": "products",
  "filter": {
    "$or": [
      { "category": "electronics", "price:$lt": 100 },
      { "category": "books", "rating:$gte": 4.5 },
      { "featured": true }
    ]
  }
}

Semantics:

(category == "electronics" AND price < 100) OR
(category == "books" AND rating >= 4.5) OR
(featured == true)

$nor ​

Logical NOR between condition groups. No group may match. Equivalent to NOT (A OR B OR ...).

Syntax:

json
{
  "$nor": [
    { "condition1": "value1" },
    { "condition2": "value2" }
  ]
}
  • Value must be an array
  • Each array item must be an object
  • Each object is an AND group

Example:

json
{
  "op": "db.find",
  "collection": "users",
  "filter": {
    "$nor": [
      { "status": "deleted" },
      { "status": "archived" }
    ]
  }
}

Semantics:

NOT (status == "deleted" OR status == "archived")

Matches users who are neither deleted nor archived.

Complex NOR example:

json
{
  "op": "db.find",
  "collection": "posts",
  "filter": {
    "$nor": [
      { "status": "draft", "author": "bot" },
      { "flags:$includes": "spam" },
      { "deleted_at:$ne": null }
    ]
  }
}

Semantics:

NOT (
  (status == "draft" AND author == "bot") OR
  (flags includes "spam") OR
  (deleted_at != null)
)

Nesting Logical Operators ​

You can nest logical operators within each other for complex queries.

Valid nesting:

json
{
  "op": "db.find",
  "collection": "products",
  "filter": {
    "$or": [
      { "category": "electronics" },
      {
        "$nor": [
          { "status": "discontinued" },
          { "stock:$lte": 0 }
        ]
      }
    ]
  }
}

Semantics:

category == "electronics" OR NOT (status == "discontinued" OR stock <= 0)

Complex nesting example:

json
{
  "op": "db.find",
  "collection": "orders",
  "filter": {
    "$or": [
      {
        "status": "completed",
        "total:$gte": 100
      },
      {
        "$and": {
          "status": "pending",
          "priority": "high",
          "_created_at:$gte": "2024-01-01T00:00:00Z"
        }
      }
    ]
  }
}

Invalid Patterns ​

❌ Cannot mix logical operators with field keys at same level:

json
{
  "status": "active",
  "$or": [
    { "role": "admin" },
    { "role": "moderator" }
  ]
}

âś… Correct - separate levels:

json
{
  "$or": [
    {
      "status": "active",
      "role": "admin"
    },
    {
      "status": "active",
      "role": "moderator"
    }
  ]
}

Or use implicit AND with OR:

json
{
  "$or": [
    { "role": "admin" },
    { "role": "moderator" }
  ]
}

Then filter by status separately if needed, or include it in each OR group.


Practical Examples ​

Find premium or active users:

json
{
  "op": "db.find",
  "collection": "users",
  "filter": {
    "$or": [
      { "subscription": "premium" },
      { "status": "active", "last_login:$gte": "2024-01-01T00:00:00Z" }
    ]
  }
}

Exclude deleted or banned users:

json
{
  "op": "db.find",
  "collection": "users",
  "filter": {
    "$nor": [
      { "status": "deleted" },
      { "status": "banned" },
      { "account_type": "suspended" }
    ]
  }
}

Complex product filter:

json
{
  "op": "db.find",
  "collection": "products",
  "filter": {
    "$or": [
      {
        "category": "electronics",
        "price:$between": [100, 500],
        "rating:$gte": 4.0
      },
      {
        "featured": true,
        "$nor": [
          { "status": "discontinued" },
          { "stock:$lte": 0 }
        ]
      }
    ]
  }
}

Filter Syntax ​

json
{
  "field:$operator": "value",
  "nested.path.to.field:$operator": "value"
}

Components:

  • field - Property name to filter on (supports dot notation for nested fields)
  • :$operator - The comparison operator
  • value - Value to compare against

Syntax Styles ​

Flat Syntax (Dot Notation) ​

Use dot notation for nested fields:

json
{
  "age:$gte": 18,
  "user.profile.city": "New York",
  "order.items.price:$lt": 100
}

Nested Syntax ​

Use nested objects to represent paths:

json
{
  "user": {
    "profile": {
      "city": "New York"
    }
  }
}

Equivalent to:

json
{
  "user.profile.city": "New York"
}

Important: The operator is always attached to the field name with a colon, not as a separate nested object.

Equality Shorthand ​

For simple equality checks, omit the operator:

json
{
  "status": "active",
  "category": "electronics"
}

Equivalent to:

json
{
  "status:$eq": "active",
  "category:$eq": "electronics"
}

Comparison Operators ​

$eq - Equal To ​

Match documents where field equals the value.

json
{
  "status:$eq": "active"
}

Shorthand:

json
{
  "status": "active"
}

Use cases:

  • Exact string matching
  • Boolean comparisons
  • Numeric equality

$ne - Not Equal To ​

Match documents where field does not equal the value.

json
{
  "status:$ne": "deleted"
}

Use cases:

  • Exclude specific values
  • Find non-matching records
  • Filter out certain states

Example:

json
{
  "op": "db.find",
  "collection": "users",
  "filter": {
    "account_status:$ne": "suspended"
  }
}

$gt - Greater Than ​

Match documents where field is greater than the value.

json
{
  "age:$gt": 18
}

Use cases:

  • Numeric comparisons
  • Date comparisons (ISO 8601 strings)
  • Price ranges

Example:

json
{
  "op": "db.find",
  "collection": "products",
  "filter": {
    "price:$gt": 99.99,
    "stock:$gt": 0
  }
}

$gte - Greater Than or Equal ​

Match documents where field is greater than or equal to the value.

json
{
  "age:$gte": 18
}

Use cases:

  • Minimum thresholds
  • Inclusive date ranges
  • Qualifying criteria

Example:

json
{
  "op": "db.find",
  "collection": "orders",
  "filter": {
    "total:$gte": 50,
    "_created_at:$gte": "2024-01-01T00:00:00Z"
  }
}

$lt - Less Than ​

Match documents where field is less than the value.

json
{
  "price:$lt": 100
}

Use cases:

  • Upper bounds
  • Budget limits
  • Date cutoffs

Example:

json
{
  "op": "db.find",
  "collection": "products",
  "filter": {
    "price:$lt": 50,
    "weight:$lt": 10
  }
}

$lte - Less Than or Equal ​

Match documents where field is less than or equal to the value.

json
{
  "price:$lte": 100
}

Use cases:

  • Maximum limits
  • Inclusive upper bounds
  • Deadline checks

Example:

json
{
  "op": "db.find",
  "collection": "tasks",
  "filter": {
    "priority:$lte": 3,
    "due_date:$lte": "2024-12-31T23:59:59Z"
  }
}

Array Operators ​

$in - Value In Array ​

Match documents where the field value is in the provided array.

json
{
  "status:$in": ["active", "pending", "processing"]
}

Use cases:

  • Multiple status values
  • Category filtering
  • Whitelist matching

Example:

json
{
  "op": "db.find",
  "collection": "users",
  "filter": {
    "role:$in": ["admin", "moderator"],
    "country:$in": ["US", "CA", "UK"]
  }
}

How it works:

  • Field is a single value (string, number, etc.)
  • Checks if that value exists in the provided array
  • field value IN ["value1", "value2", "value3"]

$nin - Value Not In Array ​

Match documents where the field value is NOT in the provided array.

json
{
  "status:$nin": ["deleted", "archived", "banned"]
}

Use cases:

  • Exclude multiple values
  • Blacklist filtering
  • Negative matching

Example:

json
{
  "op": "db.find",
  "collection": "products",
  "filter": {
    "category:$nin": ["discontinued", "out-of-stock"]
  }
}

$includes - Array Includes Value ​

Match documents where the field (which is an array) includes the provided value.

json
{
  "tags:$includes": "featured"
}

Use cases:

  • Tag matching
  • Category membership
  • Array contains checks

Example:

json
{
  "op": "db.find",
  "collection": "articles",
  "filter": {
    "tags:$includes": "tutorial",
    "categories:$includes": "programming"
  }
}

How it works:

  • Field is an array: ["tag1", "tag2", "tag3"]
  • Checks if the value exists in that array
  • "value" IN field array

$nincludes - Array Not Includes Value ​

Match documents where the field (which is an array) does NOT include the provided value.

json
{
  "tags:$nincludes": "draft"
}

Use cases:

  • Exclude items with specific tags
  • Filter out categories
  • Negative array membership

Example:

json
{
  "op": "db.find",
  "collection": "posts",
  "filter": {
    "tags:$nincludes": "private",
    "flags:$nincludes": "spam"
  }
}

$all - Array Matches All Values ​

Match documents where the field array contains ALL the provided values.

json
{
  "tags:$all": ["javascript", "tutorial", "beginner"]
}

Use cases:

  • Must have all tags
  • Required permissions
  • Complete skill sets

Example:

json
{
  "op": "db.find",
  "collection": "courses",
  "filter": {
    "topics:$all": ["javascript", "react", "nodejs"]
  }
}

How it works:

  • Field is an array: ["javascript", "react", "nodejs", "typescript"]
  • Checks if ALL provided values exist in the field array
  • All of ["javascript", "react", "nodejs"] must be in field

$any - Array Matches Any Values ​

Match documents where the field array contains ANY of the provided values.

json
{
  "tags:$any": ["featured", "popular", "trending"]
}

Use cases:

  • At least one tag matches
  • Any of several categories
  • Partial matches

Example:

json
{
  "op": "db.find",
  "collection": "products",
  "filter": {
    "badges:$any": ["sale", "new", "limited"]
  }
}

How it works:

  • Field is an array
  • Checks if AT LEAST ONE provided value exists in the field array
  • Similar to OR logic for array values

$none - Array Matches None ​

Match documents where the field array contains NONE of the provided values.

json
{
  "tags:$none": ["archived", "deleted", "hidden"]
}

Use cases:

  • Exclude multiple tags
  • Filter out unwanted categories
  • Negative matching

Example:

json
{
  "op": "db.find",
  "collection": "articles",
  "filter": {
    "flags:$none": ["spam", "inappropriate", "reported"]
  }
}

How it works:

  • Field is an array
  • Checks that NONE of the provided values exist in the field array
  • All provided values must be absent

Range Operators ​

$between - Value Between Range ​

Match documents where field value is between the start and end values (inclusive).

json
{
  "price:$between": [10, 50]
}

Use cases:

  • Price ranges
  • Date ranges
  • Age brackets
  • Score ranges

Example:

json
{
  "op": "db.find",
  "collection": "products",
  "filter": {
    "price:$between": [25.00, 100.00],
    "rating:$between": [4.0, 5.0]
  }
}

How it works:

  • Provide an array with exactly 2 values: [start, end]
  • Matches values where: start <= field_value <= end
  • Both boundaries are inclusive

Date example:

json
{
  "op": "db.find",
  "collection": "events",
  "filter": {
    "event_date:$between": ["2024-01-01T00:00:00Z", "2024-12-31T23:59:59Z"]
  }
}

Combining Operators ​

You can combine multiple operators in a single query:

json
{
  "op": "db.find",
  "collection": "products",
  "filter": {
    "price:$between": [10, 100],
    "category:$in": ["electronics", "computers"],
    "status:$ne": "discontinued",
    "tags:$includes": "featured",
    "stock:$gt": 0
  }
}

Important: You cannot use multiple operators on the same field. For range queries, use $between:

json
// ❌ Wrong - multiple conditions on same field
{
  "price:$gte": 10,
  "price:$lte": 100
}

// âś… Correct - use $between for ranges
{
  "price:$between": [10, 100]
}

Common Patterns ​

Filter Active Items ​

json
{
  "status": "active",
  "deleted_at": null
}

Date Range Query ​

json
{
  "_created_at:$between": ["2024-01-01T00:00:00Z", "2024-12-31T23:59:59Z"]
}

Price Range with Categories ​

json
{
  "price:$between": [50, 200],
  "category:$in": ["electronics", "computers"],
  "in_stock": true
}

Tag-Based Filtering ​

json
{
  "tags:$includes": "featured",
  "tags:$nincludes": "draft",
  "status": "published"
}

Multi-Condition Filter ​

json
{
  "age:$gte": 18,
  "country:$in": ["US", "CA"],
  "subscription:$ne": "cancelled",
  "permissions:$all": ["read", "write"]
}

Usage in Operations ​

db.find - Query Documents ​

json
{
  "op": "db.find",
  "collection": "products",
  "filter": {
    "price:$between": [10, 100],
    "category:$in": ["electronics", "computers"],
    "status": "active"
  }
}

db.count - Count Matching Documents ​

json
{
  "op": "db.count",
  "collection": "users",
  "filter": {
    "age:$gte": 18,
    "country:$in": ["US", "CA"]
  }
}

db.update - Update Matching Documents ​

json
{
  "op": "db.update",
  "collection": "orders",
  "filter": {
    "status": "pending",
    "_created_at:$lt": "2024-01-01T00:00:00Z"
  },
  "data": {
    "status": "expired"
  }
}

db.delete - Delete Matching Documents ​

json
{
  "op": "db.delete",
  "collection": "logs",
  "filter": {
    "_created_at:$lt": "2024-01-01T00:00:00Z",
    "level": "debug"
  }
}

db.archive - Archive Matching Documents ​

json
{
  "op": "db.archive",
  "collection": "orders",
  "filter": {
    "status": "completed",
    "_created_at:$lt": "2023-01-01T00:00:00Z"
  }
}

db.upsert - Match for Update or Insert ​

json
{
  "op": "db.upsert",
  "collection": "settings",
  "filter": {
    "user_id": "user_123",
    "setting_type": "preferences"
  },
  "update": {
    "theme": "dark"
  },
  "insert": {
    "user_id": "user_123",
    "setting_type": "preferences",
    "theme": "light"
  }
}