Query Operators Reference

Complete reference of all query operators available in the dcupl SDK.

Quick Reference

Operator Description Supported Types
eq Exact match All
find Partial text or object match string, object
gt Greater than string, number, date
gte Greater than or equal string, number, date
lt Less than string, number, date
lte Less than or equal string, number, date
typeof Type checking All
isTruthy Boolean truthiness check All
size Array/string length Array, string

Comparison Operators

eq

Matches exact values. Works with all data types.

Signature:

{ attribute: string, operator: 'eq', value: any }

Examples:

String equality
{ attribute: 'status', operator: 'eq', value: 'active' }
Number equality
{ attribute: 'price', operator: 'eq', value: 99.99 }
Boolean equality
{ attribute: 'inStock', operator: 'eq', value: true }
Reference equality
{ attribute: 'category', operator: 'eq', value: { key: 'electronics' } }
Date equality
{ attribute: 'createdAt', operator: 'eq', value: new Date('2025-01-01') }
Array equality (exact match)
{ attribute: 'tags', operator: 'eq', value: ['sale', 'featured'] }

gt

Matches values greater than the target (exclusive).

Signature:

{ attribute: string, operator: 'gt', value: number | string | Date }

Examples:

Number greater than
{ attribute: 'price', operator: 'gt', value: 100 }
// Matches: 100.01, 150, 200 (not 100)
Date greater than
{ attribute: 'orderDate', operator: 'gt', value: new Date('2025-01-01') }
// Matches: 2025-01-02 and later (not 2025-01-01)
String greater than (alphabetical)
{ attribute: 'name', operator: 'gt', value: 'M' }
// Matches: "MacBook", "Nike", "Zenith" (not "Apple", "Laptop")

gte

Matches values greater than or equal to the target (inclusive).

Signature:

{ attribute: string, operator: 'gte', value: number | string | Date }

Examples:

Number greater than or equal
{ attribute: 'price', operator: 'gte', value: 100 }
// Matches: 100, 100.01, 150, 200
Date greater than or equal
{ attribute: 'orderDate', operator: 'gte', value: new Date('2025-01-01') }
// Matches: 2025-01-01 and later

lt

Matches values less than the target (exclusive).

Signature:

{ attribute: string, operator: 'lt', value: number | string | Date }

Examples:

Number less than
{ attribute: 'stock', operator: 'lt', value: 10 }
// Matches: 0, 1, 9 (not 10)
Date less than
{ attribute: 'expiresAt', operator: 'lt', value: new Date() }
// Matches: Past dates only

lte

Matches values less than or equal to the target (inclusive).

Signature:

{ attribute: string, operator: 'lte', value: number | string | Date }

Examples:

Number less than or equal
{ attribute: 'price', operator: 'lte', value: 100 }
// Matches: 0, 50, 99.99, 100
Price range (combined)
[
  { attribute: 'price', operator: 'gte', value: 50 },
  { attribute: 'price', operator: 'lte', value: 150 },
];
// Matches: 50 to 150 inclusive

Search Operators

find

Partial text or object match. Searches within strings (substring match) or checks object property existence.

Signature:

{ attribute: string, operator: 'find', value: Record<string, unknown> | string }

Examples:

Substring search
{ attribute: 'description', operator: 'find', value: 'wireless' }
// Matches: "Wireless Mouse", "Bluetooth wireless headphones"
Case-insensitive substring search
{
  attribute: 'name',
  operator: 'find',
  value: 'laptop',
  options: { transform: ['lowercase'] }
}
// Matches: "Laptop", "LAPTOP", "laptop"
Find in nested objects
{ attribute: 'metadata', operator: 'find', value: { key: 'value' } }
// Matches items with specific nested property

Type Operators

typeof

Matches values by their JavaScript type.

Signature:

{ attribute: string, operator: 'typeof', value: TypeName }

Valid Types: 'string', 'number', 'boolean', 'object', 'undefined'

Note: To find null values, use the eq operator with value: null instead of typeof.

Examples:

Find undefined values
{ attribute: 'description', operator: 'typeof', value: 'undefined' }
// Matches items without a description
Find defined values (with invert)
{
  attribute: 'description',
  operator: 'typeof',
  value: 'undefined',
  options: { invert: true }
}
// Matches items WITH a description
Find null values (use eq, not typeof)
{ attribute: 'deletedAt', operator: 'eq', value: null }
// Matches soft-deleted items (where deletedAt is null)
Find numeric values
{ attribute: 'discount', operator: 'typeof', value: 'number' }
// Matches items with a numeric discount

isTruthy

Evaluates JavaScript truthiness.

Signature:

{ attribute: string, operator: 'isTruthy', value: boolean }

Truthy Values: true, non-zero numbers, non-empty strings, objects, arrays Falsy Values: false, 0, '', null, undefined, NaN

Examples:

Find truthy values
{ attribute: 'inStock', operator: 'isTruthy', value: true }
// Matches: inStock=true, inStock=1, inStock="yes"
Find falsy values
{ attribute: 'discontinued', operator: 'isTruthy', value: false }
// Matches: discontinued=false, discontinued=0, discontinued=null

size

Matches arrays or strings by their length.

Signature:

{ attribute: string, operator: 'size', value: number }

Examples:

Exact size match
{ attribute: 'images', operator: 'size', value: 3 }
// Matches items with exactly 3 images
Empty arrays
{ attribute: 'reviews', operator: 'size', value: 0 }
// Matches items with no reviews
String length
{ attribute: 'sku', operator: 'size', value: 8 }
// Matches SKUs with exactly 8 characters

Operator Options

All operators support these options:

transform

Applies transformations to values before comparison.

Available Transforms:

  • 'lowercase' - Convert to lowercase
  • 'trim' - Remove leading/trailing whitespace
  • 'removeWhitespace' - Remove all whitespace
Case-insensitive search
{
  attribute: 'name',
  operator: 'find',
  value: 'laptop',
  options: { transform: ['lowercase'] }
}
Multiple transforms
{
  attribute: 'email',
  operator: 'eq',
  value: 'user@example.com',
  options: { transform: ['lowercase', 'trim'] }
}

invert

Negates the operator result.

NOT equals
{
  attribute: 'status',
  operator: 'eq',
  value: 'discontinued',
  options: { invert: true }
}
// Matches items where status is NOT 'discontinued'
NOT in array
{
  attribute: 'tags',
  operator: 'find',
  value: 'hidden',
  options: { invert: true }
}
// Matches items WITHOUT 'hidden' tag

arrayValueHandling

Controls how operators match against array attribute values.

Values:

  • 'some' (default) - Match if ANY element matches
  • 'every' - Match only if ALL elements match
Match any element (default)
{
  attribute: 'tags',
  operator: 'eq',
  value: 'featured',
  options: { arrayValueHandling: 'some' }
}
// Matches if ANY tag equals 'featured'
Match all elements
{
  attribute: 'tags',
  operator: 'find',
  value: 'promo',
  options: { arrayValueHandling: 'every' }
}
// Matches only if ALL tags contain 'promo'

Query Structure

Single Condition

productList.catalog.query.addCondition({
  operator: 'eq',
  attribute: 'status',
  value: 'active',
});

Multiple Conditions (AND)

productList.catalog.query.addCondition([
  { operator: 'eq', attribute: 'status', value: 'active' },
  { operator: 'gte', attribute: 'price', value: 50 },
  { operator: 'lte', attribute: 'price', value: 150 },
]);

Grouped Conditions (OR)

productList.catalog.query.addGroup({
  groupKey: 'categories',
  groupType: 'or',
  queries: [
    { operator: 'eq', attribute: 'category', value: { key: 'electronics' } },
    { operator: 'eq', attribute: 'category', value: { key: 'computers' } },
  ],
});

Nested Groups

productList.catalog.query.addGroup({
  groupKey: 'main',
  groupType: 'and',
  queries: [{ operator: 'eq', attribute: 'active', value: true }],
  groups: [
    {
      groupKey: 'categories',
      groupType: 'or',
      queries: [
        { operator: 'eq', attribute: 'category', value: { key: 'electronics' } },
        { operator: 'eq', attribute: 'category', value: { key: 'computers' } },
      ],
    },
  ],
});
// Result: active AND (electronics OR computers)

Deep Queries

Query through references using dot notation.

Single-valued reference
{ attribute: 'customer.name', operator: 'find', value: 'John' }
// Query customer name through order->customer reference
Nested reference
{ attribute: 'customer.address.city', operator: 'eq', value: 'New York' }
// Query nested properties through references
Multi-valued reference
{ attribute: 'orders', operator: 'find', value: { status: 'completed' } }
// Find customers with completed orders

Type Reference

DcuplQuery

type DcuplQuery = {
  attribute: string;
  operator: DcuplQueryOperator;
  value: any;
  queryKey?: string;
  options?: DcuplQueryOptions;
};

DcuplQueryOperator

type DcuplQueryOperator =
  | 'eq'
  | 'find'
  | 'gt'
  | 'gte'
  | 'lt'
  | 'lte'
  | 'typeof'
  | 'isTruthy'
  | 'size';

DcuplQueryOptions

type DcuplQueryOptions = {
  transform?: ('lowercase' | 'trim' | 'removeWhitespace')[];
  invert?: boolean;
  arrayValueHandling?: 'some' | 'every';
};

DcuplQueryGroup

Groups combine multiple conditions with AND/OR logic. Nested groups are placed directly in the queries array.

type DcuplQueryGroup = {
  groupKey?: string;
  groupType?: 'and' | 'or'; // Defaults to 'and'
  queries: (DcuplQuery | DcuplQueryGroup)[];
};

Example with nested groups:

// Complex filter: active products that are either electronics OR books
const query: DcuplQueryGroup = {
  groupType: 'and',
  queries: [
    { operator: 'eq', attribute: 'status', value: 'active' },
    {
      groupType: 'or',
      queries: [
        { operator: 'eq', attribute: 'category', value: 'electronics' },
        { operator: 'eq', attribute: 'category', value: 'books' },
      ],
    },
  ],
};

See Also