> hypequery

Filters

Use typed filter helpers in metric, dataset, and measure queries.

Filters are structured query objects. They are used by metric queries, dataset queries, and filtered measures.

import {
  between,
  eq,
  gt,
  gte,
  inList,
  like,
  lt,
  lte,
  neq,
  notInList,
} from '@hypequery/datasets';

Filter helpers

eq('status', 'completed')
neq('status', 'cancelled')
gt('amount', 100)
gte('amount', 100)
lt('amount', 1000)
lte('amount', 1000)
inList('country', ['US', 'UK', 'CA'])
notInList('status', ['cancelled', 'refunded'])
between('createdAt', '2026-01-01', '2026-01-31')
like('email', '%@example.com')

Each helper returns a filter with a field, operator, and value.

eq('status', 'completed')
// { field: 'status', operator: 'eq', value: 'completed' }

Use filters in metric queries

await analytics.execute(revenue, {
  dimensions: ['country'],
  filters: [
    eq('status', 'completed'),
    gte('amount', 100),
    inList('country', ['US', 'UK', 'CA']),
  ],
});

Use filters in dataset queries

await analytics.execute(Orders, {
  dimensions: ['country', 'status'],
  measures: ['revenue', 'orderCount'],
  filters: [
    eq('status', 'completed'),
    between('createdAt', '2026-01-01', '2026-01-31'),
  ],
});

Use filters in measures

Filtered measures are useful when a business state should always be part of the aggregation.

import { dataset, dimension, eq, measure } from '@hypequery/datasets';

const Orders = dataset('orders', {
  source: 'orders',
  dimensions: {
    status: dimension.string(),
  },
  measures: {
    completedRevenue: measure.sum('amount', {
      filters: [eq('status', 'completed')],
    }),
    refundedRevenue: measure.sum('amount', {
      filters: [eq('status', 'refunded')],
    }),
  },
});

Restrict filter operators

By default, filterable dimensions become available as filters. Use the dataset filters map when you want a named filter contract or a restricted operator set.

import { dataset, dimension, measure } from '@hypequery/datasets';

const Orders = dataset('orders', {
  source: 'orders',
  dimensions: {
    status: dimension.string(),
    country: dimension.string(),
  },
  measures: {
    revenue: measure.sum('amount'),
  },
  filters: {
    status: {
      __type: 'filter_definition',
      field: 'status',
      operators: ['eq', 'neq', 'in', 'notIn'],
    },
  },
});

With this contract, status is the only exposed filter field, and only the listed operators are allowed.

Order helpers

asc and desc create structured order clauses.

import { asc, desc } from '@hypequery/datasets';

await analytics.execute(revenue, {
  dimensions: ['country'],
  orderBy: [desc('revenue'), asc('country')],
});

Tenant filters

When runtime tenancy is active, explicit filters on the tenant field are rejected. Use runtime tenant context instead.

await analytics.execute(revenue, {
  filters: [eq('tenantId', 'tenant_123')],
}, {
  runtime: {
    tenant: 'tenant_123',
  },
});
// Error: Cannot filter on tenant field "tenantId" when runtime tenancy enforcement is active.

On this page