Problem
Explore quick filters are currently displaying values in lowercase for entity types, domains, owners, and other aggregation-based filters. This creates a poor user experience as the proper casing is not preserved.
Solution
Backend support is already available via the aggregate API's sourceFields parameter (implemented in #20734). This adds a top_hits sub-aggregation that returns original-cased values from _source.
The Advanced Search query builder already uses this pattern successfully - see AdvancedSearchClassBase.ts:821 where it passes sourceFields: 'name' and parseBucketsData in SearchUtils.tsx:346 reads the original case from top_hits#top.
Implementation Steps
- For entity types: Handle on UI side directly (can be done without backend changes)
- For domains, owners, and other filters:
- In ExploreQuickFilters.tsx, when calling getAggregationOptions (~line 118), pass sourceFields for the field being queried:
- "domains.displayName" for domains
- "owners.displayName" for owners
- Similar patterns for other fields
- In getOptionsFromAggregationBucket (AdvancedSearchUtils.tsx:371), instead of using bucket.key as the label, read the original value from
bucket['top_hits#top'].hits.hits[0]._source
- Can reuse or follow the pattern from parseBucketsData function (SearchUtils.tsx:346)
Technical Context
The .keyword fields are indexed as lowercase (via lowercase_normalizer) so matching/filtering works case-insensitively, but _source always stores the original case. We aggregate on the lowercase .keyword for matching, and read the display value from _source via top_hits sub-aggregation to get proper case back.
Internal Reference
Slack thread: https://collate-inc.slack.com/archives/C09K5QBGG1J/p1774440697305259
Problem
Explore quick filters are currently displaying values in lowercase for entity types, domains, owners, and other aggregation-based filters. This creates a poor user experience as the proper casing is not preserved.
Solution
Backend support is already available via the aggregate API's
sourceFieldsparameter (implemented in #20734). This adds a top_hits sub-aggregation that returns original-cased values from_source.The Advanced Search query builder already uses this pattern successfully - see AdvancedSearchClassBase.ts:821 where it passes
sourceFields: 'name'and parseBucketsData in SearchUtils.tsx:346 reads the original case from top_hits#top.Implementation Steps
bucket['top_hits#top'].hits.hits[0]._sourceTechnical Context
The
.keywordfields are indexed as lowercase (via lowercase_normalizer) so matching/filtering works case-insensitively, but_sourcealways stores the original case. We aggregate on the lowercase .keyword for matching, and read the display value from_sourcevia top_hits sub-aggregation to get proper case back.Internal Reference
Slack thread: https://collate-inc.slack.com/archives/C09K5QBGG1J/p1774440697305259