diff --git a/docs-mintlify/docs.json b/docs-mintlify/docs.json index 0057b8293cc03..991dd0b2dbd19 100644 --- a/docs-mintlify/docs.json +++ b/docs-mintlify/docs.json @@ -608,6 +608,7 @@ "recipes/data-modeling/filtered-aggregates", "recipes/data-modeling/share-of-total", "recipes/data-modeling/period-over-period", + "recipes/data-modeling/filtering-multi-stage-measures", "recipes/data-modeling/passing-dynamic-parameters-in-a-query", "recipes/data-modeling/using-dynamic-measures", "recipes/data-modeling/dynamic-union-tables", diff --git a/docs-mintlify/docs/data-modeling/measures.mdx b/docs-mintlify/docs/data-modeling/measures.mdx index 0a443613af3bb..5aa96673c6021 100644 --- a/docs-mintlify/docs/data-modeling/measures.mdx +++ b/docs-mintlify/docs/data-modeling/measures.mdx @@ -368,6 +368,202 @@ measures: type: rank ``` +### Filter directives + +By default, a multi-stage measure inherits the query's filters into its inner +aggregation stage. The [`filter`][ref-filter-directives] parameter lets you +override this — dropping, replacing, or augmenting filters before the inner +stage runs. + +This is the building block for "share of total" against an unfiltered base, +measures that ignore certain filters (e.g., always-completed revenue), and +measures that pin themselves to a fixed slice regardless of the surrounding +query. + +The `filter` parameter accepts four sub-parameters: `mode` (`relative` — +the default — or `fixed`), `exclude`, `keep_only`, and `include`. + +**Drop a specific query filter.** The measure ignores any filter the query +places on `status`, but still respects every other filter: + + + +```yaml title="YAML" +measures: + - name: revenue_ignoring_status + multi_stage: true + sql: "{revenue}" + type: number + filter: + exclude: + - status +``` + +```javascript title="JavaScript" +measures: { + revenue_ignoring_status: { + multi_stage: true, + sql: `${revenue}`, + type: `number`, + filter: { + exclude: () => [status] + } + } +} +``` + + + +**Replace a query filter.** Strip the inherited filter on `status` and force +the inner stage to filter on `status = 'cancelled'` instead: + + + +```yaml title="YAML" +measures: + - name: revenue_cancelled + multi_stage: true + sql: "{revenue}" + type: sum + filter: + exclude: + - status + include: + - member: status + operator: equals + values: + - cancelled +``` + +```javascript title="JavaScript" +measures: { + revenue_cancelled: { + multi_stage: true, + sql: `${revenue}`, + type: `sum`, + filter: { + exclude: () => [status], + include: [ + { + member: `status`, + operator: `equals`, + values: [`cancelled`] + } + ] + } + } +} +``` + + + +**Always compute against a fixed slice.** With `mode: fixed`, all inherited +filters are discarded and only the entries in `include` apply, even when the +measure is referenced from another multi-stage measure: + + + +```yaml title="YAML" +measures: + - name: revenue_completed_fixed + multi_stage: true + sql: "{revenue}" + type: sum + filter: + mode: fixed + include: + - member: status + operator: equals + values: + - completed +``` + +```javascript title="JavaScript" +measures: { + revenue_completed_fixed: { + multi_stage: true, + sql: `${revenue}`, + type: `sum`, + filter: { + mode: `fixed`, + include: [ + { + member: `status`, + operator: `equals`, + values: [`completed`] + } + ] + } + } +} +``` + + + +**Boolean groups.** `include` clauses can be combined with `or` / `and` +groups to express compound filters: + + + +```yaml title="YAML" +measures: + - name: revenue_top_cities + multi_stage: true + sql: "{revenue}" + type: sum + filter: + include: + - or: + - member: city + operator: equals + values: + - NYC + - member: city + operator: equals + values: + - SF +``` + +```javascript title="JavaScript" +measures: { + revenue_top_cities: { + multi_stage: true, + sql: `${revenue}`, + type: `sum`, + filter: { + include: [ + { + or: [ + { + member: `city`, + operator: `equals`, + values: [`NYC`] + }, + { + member: `city`, + operator: `equals`, + values: [`SF`] + } + ] + } + ] + } + } +} +``` + + + +`filter` can also be combined with [`keep_only`][ref-filter-directives] — the +inverse of `exclude` — to forward only filters on a chosen set of members. The +same `filter` parameter is available on +[multi-stage dimensions][ref-dim-filter]. + +For end-to-end patterns — always-on baselines, replacing a filter, pinning a +baseline through chained calculations, segment-aware aggregates, and compound +boolean filters — see the +[Filtering multi-stage measures recipe][ref-filter-recipe]. + ### Conditional measures Conditional measures depend on the value of a dimension, using the @@ -426,6 +622,9 @@ measures: [ref-group-by]: /reference/data-modeling/measures#group_by [ref-reduce-by]: /reference/data-modeling/measures#reduce_by [ref-add-group-by]: /reference/data-modeling/measures#add_group_by +[ref-filter-directives]: /reference/data-modeling/measures#filter +[ref-dim-filter]: /reference/data-modeling/dimensions#filter +[ref-filter-recipe]: /recipes/data-modeling/filtering-multi-stage-measures [ref-case]: /reference/data-modeling/measures#case [ref-switch-dim]: /reference/data-modeling/dimensions#type [ref-tesseract-env]: /reference/configuration/environment-variables#cubejs_tesseract_sql_planner diff --git a/docs-mintlify/recipes/data-modeling/filtering-multi-stage-measures.mdx b/docs-mintlify/recipes/data-modeling/filtering-multi-stage-measures.mdx new file mode 100644 index 0000000000000..a7847d6be2046 --- /dev/null +++ b/docs-mintlify/recipes/data-modeling/filtering-multi-stage-measures.mdx @@ -0,0 +1,526 @@ +--- +title: Filtering multi-stage measures +description: Use filter directives to drop, replace, or pin filters on multi-stage measures and dimensions — for always-on baselines, fixed cohorts, segment-aware aggregates, and chained calculations. +--- + +## Use case + +By default, a multi-stage measure inherits all query-time filters into its +inner aggregation stage. The [`filter`][ref-filter-directives] parameter +overrides that behavior — you can drop specific filters, replace them, or pin +the measure to a fixed slice regardless of what the surrounding query asks +for. + +This is the right tool when: + +- A baseline measure should ignore a filter the query applies (e.g., + always-completed revenue, even when the query filters by `status`). +- A comparison measure should be computed against a different cohort than + the query (actual vs. last-year, region X vs. region Y). +- A measure must remain pinned to a fixed slice even when it is referenced + from another multi-stage measure higher in the chain. +- You want segment-aware aggregates that respect or ignore segment filters + selectively. + + + +The `filter` parameter on multi-stage measures and dimensions is powered by +Tesseract, the [next-generation data modeling engine][link-tesseract]. +Tesseract is currently in preview. Use the +[`CUBEJS_TESSERACT_SQL_PLANNER`][ref-tesseract-env] environment variable to +enable it. + + + +## Data model + +The examples below extend a simple `orders` cube with a `total_amount` +measure, a `completed_orders` segment, and a few dimensions: + + + +```yaml title="YAML" +cubes: + - name: orders + sql_table: ECOMMERCE.ORDERS + + dimensions: + - name: id + sql: id + type: number + primary_key: true + + - name: status + sql: "{CUBE}.status" + type: string + + - name: category + sql: "{CUBE}.category" + type: string + + - name: city + sql: "{CUBE}.city" + type: string + + - name: created_at + sql: "{CUBE}.created_at" + type: time + + segments: + - name: completed_orders + sql: "{CUBE}.status = 'completed'" + + measures: + - name: total_amount + sql: amount + type: sum + format: currency +``` + +```javascript title="JavaScript" +cube(`orders`, { + sql_table: `ECOMMERCE.ORDERS`, + + dimensions: { + id: { + sql: `id`, + type: `number`, + primary_key: true + }, + + status: { + sql: `${CUBE}.status`, + type: `string` + }, + + category: { + sql: `${CUBE}.category`, + type: `string` + }, + + city: { + sql: `${CUBE}.city`, + type: `string` + }, + + created_at: { + sql: `${CUBE}.created_at`, + type: `time` + } + }, + + segments: { + completed_orders: { + sql: `${CUBE}.status = 'completed'` + } + }, + + measures: { + total_amount: { + sql: `amount`, + type: `sum`, + format: `currency` + } + } +}) +``` + + + +Each section below adds one or more multi-stage measures on top of this base +model. + +## Always-on baseline (drop a query filter) + +Goal: a baseline `total_amount_all_statuses` that always reflects revenue +across every status, even when the query is filtered to a single status. Use +`exclude` to drop the inherited filter: + + + +```yaml title="YAML" +measures: + - name: total_amount_all_statuses + multi_stage: true + sql: "{total_amount}" + type: number + filter: + exclude: + - status +``` + +```javascript title="JavaScript" +measures: { + total_amount_all_statuses: { + multi_stage: true, + sql: `${total_amount}`, + type: `number`, + filter: { + exclude: () => [status] + } + } +} +``` + + + +A query that groups by `status` and filters to `status = 'pending'` will see +`total_amount` constrained to pending orders, but `total_amount_all_statuses` +will compute against every order — useful as a denominator for share-of-status +calculations. + +## Replace a filter (actual vs. fixed cohort) + +Goal: alongside the query's filtered `total_amount`, show +`total_amount_cancelled` — the cancelled-orders total — regardless of which +`status` the query filters by. Combine `exclude` (to drop the query's +`status` filter) with `include` (to apply your own): + + + +```yaml title="YAML" +measures: + - name: total_amount_cancelled + multi_stage: true + sql: "{total_amount}" + type: sum + filter: + exclude: + - status + include: + - member: status + operator: equals + values: + - cancelled +``` + +```javascript title="JavaScript" +measures: { + total_amount_cancelled: { + multi_stage: true, + sql: `${total_amount}`, + type: `sum`, + filter: { + exclude: () => [status], + include: [ + { + member: `status`, + operator: `equals`, + values: [`cancelled`] + } + ] + } + } +} +``` + + + +Without `exclude`, the query's `status = 'completed'` filter would be ANDed +with `status = 'cancelled'`, producing an empty set. `exclude` strips the +inherited filter first; `include` then adds the desired one. + +## Pin a baseline through a chained calculation + +`mode: relative` (the default) means that when a multi-stage measure is +wrapped by another multi-stage measure, the inner one inherits the outer's +filter state. `mode: fixed` opts out: the inner measure always starts from +an empty filter set, applying only what's in its own `include`. + +This matters for chained calculations. In the model below, `t_completed_share` +divides revenue for `category = 'books'` by total revenue for +`category = 'books'`. The numerator wraps a `fixed` measure so its denominator +stays pinned to books regardless of the surrounding query: + + + +```yaml title="YAML" +measures: + - name: books_revenue_fixed + multi_stage: true + sql: "{total_amount}" + type: sum + filter: + mode: fixed + include: + - member: category + operator: equals + values: + - books + + - name: books_completed_revenue + multi_stage: true + sql: "{books_revenue_fixed}" + type: number + filter: + include: + - member: status + operator: equals + values: + - completed + + - name: books_completed_share + multi_stage: true + sql: "1.0 * {books_completed_revenue} / NULLIF({books_revenue_fixed}, 0)" + type: number + format: percent +``` + +```javascript title="JavaScript" +measures: { + books_revenue_fixed: { + multi_stage: true, + sql: `${total_amount}`, + type: `sum`, + filter: { + mode: `fixed`, + include: [ + { + member: `category`, + operator: `equals`, + values: [`books`] + } + ] + } + }, + + books_completed_revenue: { + multi_stage: true, + sql: `${books_revenue_fixed}`, + type: `number`, + filter: { + include: [ + { + member: `status`, + operator: `equals`, + values: [`completed`] + } + ] + } + }, + + books_completed_share: { + multi_stage: true, + sql: `1.0 * ${books_completed_revenue} / NULLIF(${books_revenue_fixed}, 0)`, + type: `number`, + format: `percent` + } +} +``` + + + +Because `books_revenue_fixed` uses `mode: fixed`, its inner stage ignores +both the query's filters and the outer `status = 'completed'` filter applied +by `books_completed_revenue`. If you switched it to `mode: relative`, the +denominator would inherit `status = 'completed'` from the outer wrapper and +the ratio would always be 1. + +## Filter on segments + +`exclude` and `keep_only` accept segment names too. Use this when a multi-stage +measure should react to (or ignore) specific segment filters independently of +the query's segment selection. + +Two complementary patterns: + + + +```yaml title="YAML" +measures: + # Ignore any `completed_orders` segment the query applies. + - name: total_amount_ignoring_completion + multi_stage: true + sql: "{total_amount}" + type: number + filter: + exclude: + - completed_orders + + # Only honor the `completed_orders` segment; drop everything else. + - name: total_amount_completed_only_segment + multi_stage: true + sql: "{total_amount}" + type: number + filter: + keep_only: + - completed_orders +``` + +```javascript title="JavaScript" +measures: { + total_amount_ignoring_completion: { + multi_stage: true, + sql: `${total_amount}`, + type: `number`, + filter: { + exclude: () => [completed_orders] + } + }, + + total_amount_completed_only_segment: { + multi_stage: true, + sql: `${total_amount}`, + type: `number`, + filter: { + keep_only: () => [completed_orders] + } + } +} +``` + + + +## Compound filters with boolean groups + +`include` entries can be combined with `or` / `and` groups for compound +conditions. The example below counts revenue from large orders in the two +top-tier cities — independent of the query's own filters: + + + +```yaml title="YAML" +measures: + - name: top_city_large_orders_revenue + multi_stage: true + sql: "{total_amount}" + type: sum + filter: + mode: fixed + include: + - and: + - member: total_amount + operator: gt + values: + - "100" + - or: + - member: city + operator: equals + values: + - NYC + - member: city + operator: equals + values: + - SF +``` + +```javascript title="JavaScript" +measures: { + top_city_large_orders_revenue: { + multi_stage: true, + sql: `${total_amount}`, + type: `sum`, + filter: { + mode: `fixed`, + include: [ + { + and: [ + { + member: `total_amount`, + operator: `gt`, + values: [`100`] + }, + { + or: [ + { + member: `city`, + operator: `equals`, + values: [`NYC`] + }, + { + member: `city`, + operator: `equals`, + values: [`SF`] + } + ] + } + ] + } + ] + } + } +} +``` + + + +Boolean groups nest to any depth. Each leaf is a `{ member, operator, values }` +clause and uses the same operators as the +[REST API query format][ref-rest-query-ops]. + +## Filter directives on multi-stage dimensions + +The `filter` parameter is also available on +[multi-stage dimensions][ref-dim-filter]. The directive works the same way — +it controls which filters reach the dimension's inner aggregation stage. A +common pattern is normalizing a dimension across a fixed cohort: + + + +```yaml title="YAML" +dimensions: + - name: status_excluding_archived + sql: "{CUBE.status}" + type: string + multi_stage: true + add_group_by: + - status + filter: + mode: relative + include: + - member: status + operator: notEquals + values: + - archived +``` + +```javascript title="JavaScript" +dimensions: { + status_excluding_archived: { + sql: `${CUBE.status}`, + type: `string`, + multi_stage: true, + add_group_by: [status], + filter: { + mode: `relative`, + include: [ + { + member: `status`, + operator: `notEquals`, + values: [`archived`] + } + ] + } + } +} +``` + + + +## Choosing between `mode: relative` and `mode: fixed` + +| Mode | Inherits query filters? | Inherits outer multi-stage filters? | Use when | +|---|---|---|---| +| `relative` (default) | Yes (minus `exclude` / `keep_only`) | Yes | The measure should react to the surrounding query; you only need to tweak a few filters. | +| `fixed` | No | No | The measure must always represent the same slice — baselines, denominators in chained ratios, fixed cohorts. | + +`relative` mode pairs naturally with `exclude` / `keep_only` / `include` +overrides. `fixed` mode typically uses only `include`, because there's no +inherited state to remove. + +## See also + +- [`filter` parameter on measures][ref-filter-directives] +- [`filter` parameter on dimensions][ref-dim-filter] +- [Multi-stage measures][ref-multi-stage] +- [Calculating share of total][ref-share-of-total] +- [Calculating period-over-period changes][ref-period-over-period] + +[ref-filter-directives]: /reference/data-modeling/measures#filter +[ref-dim-filter]: /reference/data-modeling/dimensions#filter +[ref-multi-stage]: /docs/data-modeling/measures#multi-stage-measures +[ref-share-of-total]: /recipes/data-modeling/share-of-total +[ref-period-over-period]: /recipes/data-modeling/period-over-period +[ref-tesseract-env]: /reference/configuration/environment-variables#cubejs_tesseract_sql_planner +[ref-rest-query-ops]: /reference/core-data-apis/rest-api/query-format#filters-operators +[link-tesseract]: https://cube.dev/blog/introducing-next-generation-data-modeling-engine diff --git a/docs-mintlify/recipes/index.mdx b/docs-mintlify/recipes/index.mdx index ac6e5eddd03e9..0fbff7ecf66cc 100644 --- a/docs-mintlify/recipes/index.mdx +++ b/docs-mintlify/recipes/index.mdx @@ -4,7 +4,7 @@ description: Step-by-step tutorials and best practices for getting the most out mode: wide --- -Explore **38 recipes** across data modeling, calculations, analytics patterns, +Explore **39 recipes** across data modeling, calculations, analytics patterns, pre-aggregations, configuration, APIs, and AI. ## Data Modeling @@ -51,6 +51,9 @@ pre-aggregations, configuration, APIs, and AI. Calculate week-over-week, month-over-month, and other period-over-period metric changes. + + Use filter directives to drop, replace, or pin filters on multi-stage measures — for baselines, fixed cohorts, and chained calculations. + Let users select filter values and use them in calculations without filtering the entire query. diff --git a/docs-mintlify/reference/data-modeling/dimensions.mdx b/docs-mintlify/reference/data-modeling/dimensions.mdx index a08353ef48b95..caa4fdcc73e8a 100644 --- a/docs-mintlify/reference/data-modeling/dimensions.mdx +++ b/docs-mintlify/reference/data-modeling/dimensions.mdx @@ -1302,6 +1302,71 @@ cube(`fiscal_calendar`, { +### `filter` + +The `filter` parameter is used with [multi-stage dimensions][ref-multi-stage] to +control which query-time filters reach the inner aggregation stage. It accepts +the same shape as the [`filter` parameter on measures][ref-measure-filter] — +`mode` (`relative` or `fixed`), `exclude`, `keep_only`, and `include`. + + + +The `filter` parameter on multi-stage measures and dimensions is powered by +Tesseract, the [next-generation data modeling engine][link-tesseract]. Tesseract +is currently in preview. Use the +[`CUBEJS_TESSERACT_SQL_PLANNER`][ref-tesseract-env] environment variable to +enable it. + + + + + +```yaml title="YAML" +dimensions: + - name: status_normalized + type: string + sql: "{CUBE.status}" + multi_stage: true + add_group_by: + - status + filter: + mode: relative + keep_only: + - city + include: + - member: status + operator: notEquals + values: + - archived +``` + +```javascript title="JavaScript" +dimensions: { + status_normalized: { + type: `string`, + sql: `${CUBE.status}`, + multi_stage: true, + add_group_by: [status], + filter: { + mode: `relative`, + keep_only: () => [city], + include: [ + { + member: `status`, + operator: `notEquals`, + values: [`archived`] + } + ] + } + } +} +``` + + + +See the [measures reference][ref-measure-filter] for the full description of +each sub-parameter. + [ref-ai-context]: /docs/data-modeling/ai-context [ref-ref-cubes]: /reference/data-modeling/cube [ref-schema-ref-joins]: /reference/data-modeling/joins @@ -1334,4 +1399,7 @@ cube(`fiscal_calendar`, { [ref-references]: /docs/data-modeling/syntax#references [ref-filter-params]: /reference/data-modeling/context-variables#filter_params [link-encode-uri-component]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent -[ref-rest-filters]: /reference/rest-api/query-format#query-properties \ No newline at end of file +[ref-rest-filters]: /reference/rest-api/query-format#query-properties +[ref-multi-stage]: /docs/data-modeling/measures#multi-stage-measures +[ref-measure-filter]: /reference/data-modeling/measures#filter +[ref-tesseract-env]: /reference/configuration/environment-variables#cubejs_tesseract_sql_planner \ No newline at end of file diff --git a/docs-mintlify/reference/data-modeling/measures.mdx b/docs-mintlify/reference/data-modeling/measures.mdx index 8c78673af880b..16e791c25672f 100644 --- a/docs-mintlify/reference/data-modeling/measures.mdx +++ b/docs-mintlify/reference/data-modeling/measures.mdx @@ -766,6 +766,217 @@ dimensions will be included in the inner stage's `GROUP BY` but will *not* appea in the outer aggregation — they are used only to define the granularity at which the base measure is computed before the outer aggregation is applied. +### `filter` + +The `filter` parameter is used with [multi-stage measures][ref-multi-stage] to +control which query-time filters reach the inner aggregation stage. It allows +you to drop, replace, or augment filters that would otherwise be inherited from +the query. + +This is commonly used when a multi-stage calculation needs to ignore filters on +specific dimensions (for example, computing a "share of total" against an +unfiltered base) or apply its own additional filters on top of the query's +filters. + + + +The `filter` parameter on multi-stage measures and dimensions is powered by +Tesseract, the [next-generation data modeling engine][link-tesseract]. Tesseract +is currently in preview. Use the +[`CUBEJS_TESSERACT_SQL_PLANNER`][ref-tesseract-env] environment variable to +enable it. + + + + + +```yaml title="YAML" +measures: + - name: revenue + sql: amount + type: sum + + - name: revenue_completed_only + multi_stage: true + sql: "{revenue}" + type: number + filter: + mode: relative + exclude: + - status + include: + - member: status + operator: equals + values: + - completed + - or: + - member: city + operator: equals + values: + - NYC + - member: city + operator: equals + values: + - SF +``` + +```javascript title="JavaScript" +measures: { + revenue: { + sql: `amount`, + type: `sum` + }, + + revenue_completed_only: { + multi_stage: true, + sql: `${revenue}`, + type: `number`, + filter: { + mode: `relative`, + exclude: () => [status], + include: [ + { + member: `status`, + operator: `equals`, + values: [`completed`] + }, + { + or: [ + { + member: `city`, + operator: `equals`, + values: [`NYC`] + }, + { + member: `city`, + operator: `equals`, + values: [`SF`] + } + ] + } + ] + } + } +} +``` + + + +The `filter` parameter accepts an object with the following keys, all of which +are optional. At least one of `exclude`, `keep_only`, or `include` must be +provided. + +#### `mode` + +Controls how the inner stage's filter set is composed. Can be either of: + +| Mode | Description | +|---|---| +| `relative` (default) | Start from the filters that would otherwise apply to the inner stage (the query's filters minus anything that was already consumed by an outer multi-stage wrapper), then apply `exclude` / `keep_only` / `include` on top. | +| `fixed` | Ignore the inherited filter state entirely. The inner stage starts from an empty set of filters and only the entries listed in `include` are applied. | + +Use `fixed` when a multi-stage measure must always be computed against the same +slice of data regardless of which other multi-stage measures wrap it. Use +`relative` (the default) when the calculation should still react to the +surrounding query. + +#### `exclude` + +A list of dimension or segment names. Any query-time filter on a listed member +is dropped before the inner stage runs. This is useful when a calculation must +be insensitive to a specific dimension's filter (e.g., a denominator that +should not be filtered by `status` even when the query filters by it). + +In JavaScript, `exclude` is written as a function returning an array of +dimension references — the same pattern as +[`group_by`](#group_by) and [`reduce_by`](#reduce_by): + + + +```yaml title="YAML" +filter: + exclude: + - status + - completed_orders # may also reference a segment +``` + +```javascript title="JavaScript" +filter: { + exclude: () => [status, completed_orders] +} +``` + + + +#### `keep_only` + +The inverse of `exclude`. A list of dimension or segment names — only filters +on the listed members are forwarded to the inner stage; everything else is +dropped. + + + +```yaml title="YAML" +filter: + keep_only: + - city +``` + +```javascript title="JavaScript" +filter: { + keep_only: () => [city] +} +``` + + + +#### `include` + +A list of filter clauses that are added on top of the resulting filter set. +Each clause is either a single-member filter or a boolean group: + +- A **member filter** has the shape `{ member, operator, values }`, where + `operator` matches the operators available in the + [REST API query format][ref-rest-query-ops] (`equals`, `notEquals`, + `contains`, `notContains`, `startsWith`, `notStartsWith`, `endsWith`, + `notEndsWith`, `in`, `notIn`, `gt`, `gte`, `lt`, `lte`, `set`, `notSet`, + `inDateRange`, `notInDateRange`, `onTheDate`, `beforeDate`, `beforeOrOnDate`, + `afterDate`, `afterOrOnDate`, `measureFilter`). `values` is required for all + operators except `set` and `notSet`. +- A **boolean group** has the shape `{ or: [ ... ] }` or `{ and: [ ... ] }`, + containing nested member filters or further boolean groups. + +`exclude` and `include` can be combined to *replace* a filter — `exclude` first +strips the inherited filter on a member, then `include` adds the desired one. + + + +```yaml title="YAML" +filter: + exclude: + - status + include: + - member: status + operator: equals + values: + - cancelled +``` + +```javascript title="JavaScript" +filter: { + exclude: () => [status], + include: [ + { + member: `status`, + operator: `equals`, + values: [`cancelled`] + } + ] +} +``` + + + ### `time_shift` The `time_shift` parameter is used to configure a [time shift][ref-time-shift] for a @@ -1431,6 +1642,8 @@ cube(`orders`, { [ref-apis]: /reference [ref-rolling-window]: /docs/data-modeling/measures#rolling-windows [link-tesseract]: https://cube.dev/blog/introducing-next-generation-data-modeling-engine +[ref-tesseract-env]: /reference/configuration/environment-variables#cubejs_tesseract_sql_planner +[ref-rest-query-ops]: /reference/core-data-apis/rest-api/query-format#filters-operators [ref-multi-stage]: /docs/data-modeling/measures#multi-stage-measures [ref-time-shift]: /docs/data-modeling/measures#time-shift [ref-nested-aggregate]: /docs/data-modeling/measures#nested-aggregates