Skip to content

Commit 3eb4789

Browse files
authored
Update publisher filter syntax in notebook docs (#309)
* Update publisher filter syntax docs Publisher's filter annotation syntax changed from JSON-style (`#(filter) {"type": "Star"}` on dimensions plus a `##(filters)` notebook annotation) to source-level declarations with name=/dimension=/type= parameters. Notebooks now inherit filters automatically from imported sources—no notebook-level configuration needed. Updates notebooks.malloynb to match the spec at malloydata/publisher/docs/filters.md, including the new filter types (equal/in/like/greater_than/less_than), the implicit/required flags, and the multiple-filters-per-dimension pattern for date ranges. * DCO Remediation Commit for James Swirhun <james@credibledata.com> I, James Swirhun <james@credibledata.com>, hereby add my Signed-off-by to this commit: ccff94b Signed-off-by: James Swirhun <james@credibledata.com> --------- Signed-off-by: James Swirhun <james@credibledata.com>
1 parent 62ec219 commit 3eb4789

1 file changed

Lines changed: 54 additions & 47 deletions

File tree

src/documentation/user_guides/notebooks.malloynb

Lines changed: 54 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -118,88 +118,95 @@ my-analytics/
118118

119119
## Interactive Filters
120120

121-
Notebooks can include interactive dropdown filters that allow viewers to filter query results dynamically. When a user selects filter values, all queries in the notebook automatically re-execute with those filters applied.
121+
Notebooks can expose interactive filter controls that let viewers narrow query results dynamically. When a user changes a filter value, Publisher rewrites each query with a `where:` clause on the server and re-executes the affected cells.
122122

123123
> **Note:** Interactive filters are rendered when viewing notebooks via [Publisher](publishing/publishing.malloynb) or the Publisher SDK. They are not currently displayed in VS Code—that capability is coming soon.
124124

125125
### How It Works
126126

127-
1. **Annotate dimensions** in your Malloy source files to mark them as filterable
128-
2. **Add a `##(filters)` annotation** in your notebook to specify which dimensions appear as filter controls
129-
3. When published, the notebook displays filter dropdowns that users can interact with
127+
Filters are declared on the **source** using `#(filter)` annotations. Publisher parses these annotations, exposes filter metadata through its API, renders widgets above the notebook, and injects matching `where:` clauses into queries at execution time. Any notebook that imports the source automatically inherits its filters—no notebook-level configuration is required.
130128

131-
### Step 1: Annotate Filterable Dimensions
129+
### Declaring Filters
132130

133-
In your Malloy source file, add `#(filter)` annotations to dimensions you want to expose as filters:
131+
Place one or more `#(filter)` annotations immediately above a source definition:
134132

135133
```malloy
136-
source: flights is duckdb.table('data/flights.parquet') extend {
137-
dimension:
138-
// Multi-select dropdown for string values
139-
#(filter) {"type": "Star"}
140-
origin_code is origin
141-
142-
// Date range picker
143-
#(filter) {"type": "DateMinMax"}
144-
flight_departure is dep_time
145-
146-
join_one: carriers with carrier
134+
#(filter) name=Manufacturer dimension=Manufacturer type=in
135+
#(filter) name=Subject dimension=Subject type=like
136+
#(filter) name=Major_Recall dimension="Major Recall" type=equal
137+
#(filter) name=Recall_After dimension="Report Received Date" type=greater_than
138+
#(filter) name=Recall_Before dimension="Report Received Date" type=less_than
139+
source: recalls is duckdb.table('data/auto_recalls.csv') extend {
140+
measure:
141+
recall_count is count()
147142
}
143+
```
144+
145+
### Annotation Syntax
148146

149-
source: carriers is duckdb.table('data/carriers.parquet') extend {
150-
dimension:
151-
#(filter) {"type": "Star"}
152-
nickname is nickname_old
153-
}
154147
```
148+
#(filter) [name=NAME] dimension=DIMENSION type=TYPE [implicit] [required]
149+
```
150+
151+
| Parameter | Required | Description |
152+
|-----------|----------|-------------|
153+
| `name` | No | Unique identifier for the filter, used as the API parameter key. Defaults to the dimension name. |
154+
| `dimension` | Yes | The dimension the filter targets. Quote with `"..."` if it contains spaces. |
155+
| `type` | Yes | Comparator type (see below). |
156+
| `implicit` | No | Flag. Hides the filter from the UI and API summaries—useful for row-level security. |
157+
| `required` | No | Flag. The server returns a 400 error if a required filter has no value at query time. |
155158

156159
### Filter Types
157160

158-
| Type | UI Component | Use Case |
159-
|------|--------------|----------|
160-
| `Star` | Multi-select dropdown | String fields with discrete values |
161-
| `MinMax` | Numeric input | Numeric fields |
162-
| `DateMinMax` | Date range picker | Date/timestamp fields |
163-
| `Boolean` | Toggle selector | Boolean fields |
161+
| Type | Malloy Clause | Use Case |
162+
|------|---------------|----------|
163+
| `equal` | `dimension = 'value'` | Exact match on a single value |
164+
| `in` | `dimension ? 'a' \| 'b' \| 'c'` | Match any of multiple values |
165+
| `like` | `dimension ~ '%value%'` | Substring / pattern matching |
166+
| `greater_than` | `dimension > value` | Range filter (after, minimum) |
167+
| `less_than` | `dimension < value` | Range filter (before, maximum) |
164168

165-
### Step 2: Add Notebook Filter Annotation
169+
### Multiple Filters on the Same Dimension
166170

167-
In your notebook, add a `##(filters)` annotation in the code cell that imports your model. The annotation lists which dimensions should appear as filters using `source.dimension` format:
171+
Give each filter a unique `name` to declare multiple controls over the same dimension. This is the standard pattern for date ranges:
168172

169173
```malloy
170-
##(filters) ["flights.origin_code", "carriers.nickname", "flights.flight_departure"]
171-
import {flights, carriers} from 'flights.malloy'
174+
#(filter) name=Start_Date dimension="Created At" type=greater_than
175+
#(filter) name=End_Date dimension="Created At" type=less_than
172176
```
173177

174-
The filter type for each dimension is determined by the `#(filter)` annotation on that dimension in the source file.
178+
Each filter operates independently and maps to its own API parameter.
179+
180+
### Widget Rendering
181+
182+
Publisher selects the widget type based on the underlying dimension's Malloy data type:
183+
184+
| Dimension Type | Widget |
185+
|---------------|--------|
186+
| `string` (with `in` or `like`) | Searchable multi-select or text input |
187+
| `boolean` | Toggle / dropdown |
188+
| `date` / `timestamp` | Date picker |
189+
| `number` | Numeric input |
190+
191+
Implicit filters are hidden from the UI but still applied server-side.
175192

176193
### Custom Labels
177194

178-
By default, filters display the dimension field name. You can customize the label using the `# label="..."` annotation in your source file:
195+
By default, filter widgets display the dimension name. Use the `# label="..."` annotation on the dimension to customize it:
179196

180197
```malloy
181198
source: recalls is duckdb.table('data/recalls.csv') extend {
182199
dimension:
183-
#(filter) {"type": "Star"}
184200
# label="Vehicle Manufacturer"
185201
Manufacturer is Manufacturer_old
186202
}
187203
```
188204

189-
### Match Types
190-
191-
Each filter type supports different match types that users can select:
192-
193-
| Filter Type | Available Match Types |
194-
|------------|----------------------|
195-
| Star | Equals, Contains |
196-
| MinMax | Equals, Less Than, Greater Than, Between |
197-
| DateMinMax | Equals, Before, After, Between |
198-
| Boolean | Equals (True/False) |
199-
200205
### Example
201206

202-
See the [Carrier Analysis notebook](https://github.com/credibledata/malloy-samples/blob/main/faa/carrier_analysis.malloynb#L4) and [Auto Recalls notebook](https://github.com/credibledata/malloy-samples/blob/main/auto_recalls/README.malloynb#L10) for working examples of interactive filters.
207+
See the [Auto Recalls notebook](https://github.com/credibledata/malloy-samples/blob/main/auto_recalls/README.malloynb) for a working example of interactive filters.
208+
209+
For the full specification—including API details, bypass filters, and MCP tool integration—see the [Publisher filter documentation](https://github.com/malloydata/publisher/blob/main/docs/filters.md).
203210

204211
---
205212

0 commit comments

Comments
 (0)