Skip to content

Commit 1f05f0d

Browse files
committed
Add RFC for extended search filters.
Signed-off-by: Jackson Goerner <[email protected]>
1 parent 1c53c71 commit 1f05f0d

File tree

6 files changed

+196
-0
lines changed

6 files changed

+196
-0
lines changed

assets/000/acryl-filter.png

19.5 KB
Loading

assets/000/radio-example.png

15.3 KB
Loading

assets/000/search-example.png

13.4 KB
Loading

assets/000/tag-key.png

20.3 KB
Loading

assets/000/tag-value.png

15.5 KB
Loading
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
- Feature Name: extended_search_filters
2+
- Start Date: 2025-01-06
3+
- RFC PR: [amundsen-io/rfcs#0000](https://github.com/amundsen-io/rfcs/pull/0000) (after opening the RFC PR, update this with a link to it and update the file name)
4+
- Amundsen Issue: [amundsen-io/amundsen#0000](https://github.com/amundsen-io/amundsen/issues/0000) (leave this empty for now)
5+
6+
# Extended Search Filters
7+
8+
## Summary
9+
10+
We're looking to improve the advanced search experience in Amundsen by providing two new ways to filter data in the UI, namely the radio select filter and dropdown select filter.
11+
12+
## Motivation
13+
14+
### Why are we doing this?
15+
16+
One pain point we've found with Amundsen's advanced search is that for new users, the experience can be quite daunting, and asking even simple questions requires some specific knowledge of the cluster-database-schema-table naming scheme. Some of this pain stems from the fact that all current search filters are free text - users have to enter in the exact (or wildcarded) expression they are filtering on.
17+
18+
### What use cases does it support?
19+
20+
In our experience we've found this useful for fields that are sparse in value, and so showing all options to the user is more effective than providing them the ability to filter down with free text.
21+
22+
Depending on implementation, this can also support dynamic fields that can fill options from the react state. In our use-case, this was used to provide context dependant dropdown options for table tags of the form `KEY = VALUE`.
23+
24+
### What is the expected outcome?
25+
26+
The expected outcome is that amundsen developers are provided with more configuration to customise their advanced search experience.
27+
28+
## Guide-level Explanation (aka Product Details)
29+
30+
Amundsen's advanced search page contains multiple filters on the left hand side of the page. Deciding what particular filters to show is decided via configuration provided in `frontend/amundsen_application/static/js/config/`. In particular the AppConfig key `resourceConfig[<resource>][filterCategories]`.
31+
32+
This is an array of `FilterConfig` objects which determine what specific filters can be shown and how they are rendered.
33+
34+
Two of these filters focused on removing friction between your users and the search page are the **radio select** and **dropdown options**.
35+
36+
### Radio Select
37+
38+
The radio select will render multiple options of your choosing, allowed you to select/deselect these options, and have the page automatically rerender the search results based on these options. For example, suppose we've got many tables in our system, but these all live in a few main database locations, then a radio select is probably the correct filter category to use:
39+
40+
![Example of radio filter](/assets/000/radio-example.png)
41+
42+
Radio selects can support multiple selections, or just a single selection at a time. The options rendered is also completely configurable, and can show an icon alongside the option. If you'd like to provide an option for 'everything else' that will simply match anything not covered by the visible options, you can include that too (This is the 'Other' option in the image above).
43+
44+
### Dropdown Select
45+
46+
The dropdown select will render a searchable dropdown which users can type into and select their preferred options. The contents of this dropdown are also configurable.
47+
48+
For example, suppose we've got about 300 schemas in our system, which is too much for a radio button scheme, but not enough to warrant avoiding a better experience than freetext entirely. We can show the schemas in a searchable dropdown, allowing the users to see all schemas available.
49+
50+
![Example of Dropdown search filter](/assets/000/search-example.png)
51+
52+
This could also rerender the search options based on the database filter values mentioned above! So when the snowflake checkbox isn't checked, snowflake schemas would not be shown in the dropdown.
53+
54+
One more example of dynamic rendering for search is in table tags. Users might have tagged resources with a `KEY=VALUE` format, so `my_schema.my_table` might have tags `ETL_OWNER=hsimpson`, `YEAR_INTRODUCED=2022`, etc. In order to adequately filter by this in our search page, you might have two dropdowns; One for selecting the tag key, and another for selecting the tag value.
55+
56+
![Example of tag key options](/assets/000/tag-key.png)
57+
![Example of tag value options](/assets/000/tag-value.png)
58+
59+
The tag value dropdown can then render it's search options based on the option selected for tag key.
60+
61+
## UI/UX-level Explanation
62+
63+
Largely the same as the Guide-level explanation - The advanced search page has the ability to show more search options. See the guide level explanation for example images of UI.
64+
65+
## Reference-level Explanation (aka Technical Details)
66+
67+
Adds two more filter categories in the config types:
68+
69+
* `RadioFilterCategory`
70+
* `DropdownFilterCategory`
71+
72+
### RadioFilterCategory
73+
74+
`RadioFilterCategory` has the following extra configuration keys:
75+
76+
```ts
77+
interface RadioFilterCategory extends BaseFilterCategory {
78+
getOptions: (state: GlobalState) => RadioOption[]; // Function to determine what options to render
79+
wildcard: boolean; // Whether to show a catch-all wildcard option
80+
wildcardOption?: RadioOption; // What to render the wildcardOption as
81+
defaultOptions: string[]; // The default selection of options on page load (in terms of patterns)
82+
multiple?: boolean; // Whether to allow multiple box selections (default: true)
83+
}
84+
```
85+
86+
`RadioOption` has the following schema:
87+
88+
```ts
89+
interface RadioOption {
90+
label: string; // The visible label for this option
91+
pattern: string[] | string; // What string/strings to include in the filter parameters when this checkbox is clicked
92+
icon?: string; // Icon class, if you want it rendered (For example, `icon-snowflake`)
93+
wildcard?: boolean // True only for the wildcard option
94+
}
95+
```
96+
97+
The selected Radio Options are then combined to form a search query.
98+
99+
#### Example
100+
101+
Suppose we had the following options:
102+
103+
```ts
104+
[
105+
{ label: 'Snowflake', pattern: 'snowflake', icon: 'icon-snowflake' },
106+
{ label: 'Data Sources', pattern: ['kafka', 's3'] },
107+
{ label: 'Data Sinks', pattern: ['looker', 'tableau']},
108+
{ label: 'Other', pattern: [], wildcard: true }
109+
]
110+
```
111+
112+
And the `defaultOptions` `['snowflake', 'looker', 'tableau']`. Then on page load the selection of 'Snowflake' and 'Data Sinks' would be made, and the filter value sent off to the search endpoint would be `['snowflake', 'looker', 'tableau']` with the `OR` `filterOperation`.
113+
114+
#### Extra required feature - NOR filter.
115+
116+
If instead 'Snowflake' and 'Other' were selected, then we want to show all results *except* the Data Sources and Data Sinks.
117+
Then the following value would be sent to the search endpoint: `['looker', 'tableau', 'kafka', 's3']` with the new filterOperation `NOR`.
118+
119+
`NOR`'s implementation on the search side is very simple:
120+
121+
```python
122+
# Current OR implementation
123+
if filter.operation == 'OR':
124+
filter_queries.append(Q(BOOL_QUERY, should=queries_per_term, minimum_should_match=1))
125+
# NEW: NOR filter operation
126+
elif filter.operation == 'NOR':
127+
filter_queries.append(~Q(BOOL_QUERY, should=queries_per_term, minimum_should_match=1))
128+
```
129+
130+
### DropdownFilterCategory
131+
132+
`DropdownFilterCategory` has the following extra configuration keys:
133+
134+
```ts
135+
interface DropdownFilterCategory extends BaseFilterCategory {
136+
getOptions: (state: GlobalState) => DropdownOption[]; // Function to determine what options to render
137+
multiple?: boolean; // Whether to allow multiple dropdown selections (default: false)
138+
}
139+
```
140+
141+
`DropdownOption` has the following schema:
142+
143+
```ts
144+
interface DropdownOption {
145+
label: string; // The visible label for this option - also the unique key
146+
pattern: string[] | string; // What string/strings to include in the filter parameters when this dropdown is selected
147+
icon?: string; // Icon class, if you want it rendered (For example, `icon-snowflake`)
148+
}
149+
```
150+
151+
The selected Dropdown Options are then combined to form a search query, similar to the RadioFilter.
152+
153+
The dropdown is implemented using the `react-select` library.
154+
155+
## Drawbacks
156+
157+
| Drawback | Comment |
158+
| -------- | ------- |
159+
| Upfront implementation cost | This is small, as this feature has been implemented in our fork (although not up to standard.) |
160+
| Impact on onboarding of Amundsen | Slightly complicates the experience since we're adding more stuff. |
161+
| Complicates the filter definition configuration by allowing dynamically rendered results | Somewhat of a departure from the current filter design in pursuit of a more configurable / streamlined user experience. |
162+
163+
## Alternatives
164+
165+
A similar experience could be achieved by doing some of the following:
166+
167+
* Altering the search bar to allow 'flags' to be added and have this turn into filters ( Search: `my_table tag:<value>` )
168+
* Have tags/databases in search results be clickable to filter down results based on this.
169+
170+
Both of these, while powerful, are less intuitive for users and less controlled by the maintainer, and so they weren't favoured over the new filters.
171+
172+
## Prior art
173+
174+
This radio select feature is present in acryl/datahub:
175+
176+
![Example of search view in Acryl](/assets/000/acryl-filter.png)
177+
178+
Although I am not involved with other data communites and am unaware of the opinions / experiences of them.
179+
180+
## Unresolved questions
181+
182+
Not many unresolved questions since this is already implemented and in use for us, but some questions relating to wider community adoption:
183+
184+
* How much configuration of these filters is preferred vs. unnecessarily complicating the process?
185+
* What other-use cases are available for such filters, and are there changes necessary to make this work?
186+
187+
## Future possibilities
188+
189+
There is the possibility for other, more adventurous, filters:
190+
191+
* Filter by tables upstream/downstream of those fitting the other filters
192+
* Filter by clustering of users (most of my table's users are in compliance, marketing, engineering, etc.)
193+
194+
There is also the possibility to streamline the process of rendering dynamic results as well, since implementing many of the examples above would require more than just configuration (You need to generate the ducks functionality to refresh things like tag values and schemas).
195+
196+
So a feature to make this refresh functionality available via configuration would also be neat.

0 commit comments

Comments
 (0)