Filtering
Filters define which records a semantic query returns. Apply filters to dimensions, measurements, and calculated fields to narrow your result set. The Semantic Query API supports multiple filter types that operate at different stages of query execution: context filters run before all other filters, standard query filters apply to pre-aggregation data, and aggregate filters (HAVING) operate on post-aggregation results.
The Semantic Query API supports two operator representations:
- PascalCase operators (
"GreaterThan","In","StartsWith") infilters[]arrays withinflatten_filterstructures and model-defined filters. - SCREAMING_SNAKE operators (
BINARY_OPERATOR_GREATER_THAN,BINARY_OPERATOR_IN) in structuredbinary_predicatefilter objects.
Both forms are semantically equivalent; the wire representation differs by context.
Filters can be defined at authoring time as part of the Semantic Data Model. Model-level filters apply globally to all queries against that model, while Semantic Data Object filters apply only when that object is queried. For details on defining filters in the model, see Semantic Data Object Field in the Authoring API.
Filters are evaluated in layers. Semantic Data Object filters apply first, followed by relationships, then model-level (global) filters. Context filters are applied as an independent pre-filter, and aggregate filters (HAVING) are applied last, after aggregation. Within a single layer, conditions can be combined with OR; between layers, the layers are combined with AND.
Use comparison operators to filter numeric, date, datetime, and text fields. Supported operators include equals, not equals, greater than, less than, greater than or equal, and less than or equal. Case-insensitive variants are available for text comparisons.
The structured predicate form uses BINARY_OPERATOR_* constants:
BINARY_OPERATOR_EQUALSBINARY_OPERATOR_NOT_EQUAL_TOBINARY_OPERATOR_GREATER_THANBINARY_OPERATOR_LESS_THANBINARY_OPERATOR_GREATER_THAN_OR_EQUAL_TOBINARY_OPERATOR_LESS_THAN_OR_EQUAL_TOBINARY_OPERATOR_EQUALS_IGNORE_CASEBINARY_OPERATOR_NOT_EQUALS_IGNORE_CASE
Filter text fields using pattern-matching operators. Text operators support case-sensitive and case-insensitive variants.
In flatten_filter PascalCase form:
Contains/ContainsIgnoreCaseNotContains/DoesNotContainIgnoreCaseStartsWith/StartsWithIgnoreCaseDoesNotStartWith/DoesNotStartWithIgnoreCaseEndsWith/EndsWithIgnoreCaseDoesNotEndWith/DoesNotEndWithIgnoreCase
In structured predicate SCREAMING_SNAKE form:
BINARY_OPERATOR_CONTAINSBINARY_OPERATOR_STARTS_WITHBINARY_OPERATOR_ENDS_WITH
(with corresponding _IGNORE_CASE and NOT_* variants)
Use In and NotIn operators to filter against a list of values. The Values operator is deprecated; use In instead.
In flatten_filter PascalCase form: "operator": "In" or "operator": "NotIn" with a "values": [...] array.
In structured predicate form: BINARY_OPERATOR_IN or BINARY_OPERATOR_NOT_IN.
Performance: Use
InandNotInwith a value list instead of chainingEqualsconditions withOR.
Distinguish between IsNull / IsNotNull (any data type) and IsEmpty / IsNotEmpty (text fields only). IsEmpty matches both NULL and empty string "", while IsNotEmpty excludes both.
In PascalCase form: "operator": "IsNull", "IsNotNull", "IsEmpty", "IsNotEmpty".
In SCREAMING_SNAKE form: BINARY_OPERATOR_IS_NULL, BINARY_OPERATOR_IS_NOT_NULL, BINARY_OPERATOR_IS_EMPTY, BINARY_OPERATOR_IS_NOT_EMPTY.
Use Between (or BINARY_OPERATOR_BETWEEN) to filter numeric, date, or datetime fields within an inclusive range. Provide both boundaries in rangeValues with lower_boundary and upper_boundary.
In PascalCase form (model filters): "operator": "Between", "value": "lower | upper" (pipe-delimited string).
In structured form: "binary_operator": "BINARY_OPERATOR_BETWEEN", "right_expression": { "range_values": { "lower_boundary": {...}, "upper_boundary": {...} } }.
Performance: Use
Betweenfor a range instead of separateGreaterThanOrEqualandLessThanOrEqualconditions; a single range predicate lets the engine prune partitions on date and numeric columns.
Filter date and datetime fields using BINARY_OPERATOR_BETWEEN with range_values. Specify ISO 8601 datetime strings in datetime_expression for boundaries.
The datetime_expression value must be an ISO 8601 formatted timestamp that includes a time zone offset (either Z for UTC or a ±hh:mm offset). Fractional seconds are optional and support up to nanosecond precision. Accepted formats include:
2023-01-10T16:00:00.000-08:002023-01-10T16:00:00Z2023-01-10T16:00:00.123456789+05:302023-01-10T00:00:00-08:00
Relative date filters compute dynamic date ranges based on an anchor date (defaulting to the current date). Use relativeDateRange with datePart, startOffset, and endOffset to define the window.
Supported datePart values:
- Time:
Minute,Hour,Day,Week,Month,Quarter,Year - Fiscal:
Fiscal_Week,Fiscal_Month,Fiscal_Quarter,Fiscal_Year - Localized:
Localized_Week
Set useCurrentDateAsEndDate: true to anchor the range to the current date, or provide an explicit anchorDate as an ISO 8601 datetime string.
Combine multiple filters using logical operators. In structured predicate form, use logical_binary_predicate with logical_binary_operator (LOGICAL_BINARY_OPERATOR_AND, LOGICAL_BINARY_OPERATOR_OR, LOGICAL_BINARY_OPERATOR_NOT). In flatten_filter form, use a filterLogic string with filter indices and parentheses (e.g., "(1 AND 2) OR 3").
Context filters apply before all other query filters (except Semantic Data Model and Semantic Data Object filters). Use semantic_context.context_filter (or the deprecated top-level context_filter) to define an independent pre-filter that all subsequent filters build upon.
Performance: Use a
context_filterfor high-selectivity baseline conditions. Context filters apply before other query filters, shrinking the working set for the whole query.
Flatten filters combine multiple filter conditions using a logical expression string. Define an array of filter objects in filters[], each with a PascalCase operator, fieldName, and value or values. Reference filters by 1-based index in the filterLogic string (e.g., "(1 AND 2) OR (3 AND 4)").
Aggregate filters apply to post-aggregation results, equivalent to SQL HAVING clauses. Use aggregate_filter with a binary_predicate that references an aggregated expression (typically a calculated field with an aggregation function).
Performance: Apply row-level
filterconditions rather thanaggregate_filter(HAVING) whenever possible. Row-level filters reduce rows before aggregation; aggregate filters run after grouping and cannot reduce the amount of data scanned.
Advanced dimension filters enable Top-N and Bottom-N queries, returning only the top or bottom N dimension values ranked by an aggregated measure. Use advanced_dimension_filters_v2[] with the AdvancedDimension operator and a top_bottom_criteria object specifying top_bottom_limit, is_top, and a measure expression.
Performance: A filter that references an LOD expression disables the window-function optimization and forces a subquery-and-join plan, which is more expensive.
| Field (wire name) | Type | Required | Description |
|---|---|---|---|
filter | Predicate | N | Standard query filter; applies before aggregation. |
context_filter | Predicate | N | Context filter; applies before query filter (deprecated at top level; use semantic_context.context_filter). |
aggregate_filter | Predicate | N | Aggregate filter; applies to post-aggregation results (HAVING clause). |
flatten_filter | FlattenFilter | N | Flatten filter with logical expression indexing an array of PascalCase filter objects. |
advanced_dimension_filters_v2 | AdvancedDimensionFilter[] | N | Top-N / Bottom-N filters on dimension values ranked by a measure. |
binary_predicate | BinaryPredicate | N | Binary comparison with left/right expressions and a binary_operator. |
logical_binary_predicate | LogicalBinaryPredicate | N | Combines two predicates with logical_binary_operator (AND / OR / NOT). |
binary_operator | String (enum) | Y* | Operator constant (e.g., BINARY_OPERATOR_EQUALS, BINARY_OPERATOR_GREATER_THAN). |
operator | String (PascalCase) | Y* | PascalCase operator in flatten_filter form (e.g., "GreaterThan", "In", "StartsWith"). |
range_values | RangeValues | N | Inclusive range boundaries (lower_boundary, upper_boundary) for Between operator. |
relativeDateRange | RelativeDateRange | N | Dynamic date range with datePart, startOffset, endOffset, anchorDate. |
For the full request schema, see Request Reference.
IsEmpty/IsNotEmptyapply to text fields only.IsNull/IsNotNullapply to fields of any type.IsNotEmptyis stricter thanIsNotNull: for a text field that can hold"",IsNotNullkeeps empty-string records whileIsNotEmptyfilters them out.- Aggregate filters (HAVING) require an aggregated expression. The
aggregate_filterpredicate must reference a measure or calculated field with an aggregation function, not a raw dimension.
- Semantic Data Object Field — Authoring API for defining model-level filters.
- Grouping — How grouping interacts with filter order-of-operations.
- Aggregation & Totals — Aggregate filters (HAVING) apply after aggregation.
- Calculated Fields — Use filters within calculated field expressions.
- Request Reference — Complete field schema for filters and predicates.