Skip to content

feat: Add Lucene/SQL search filter to Service Map page#2319

Draft
MikeShi42 wants to merge 4 commits into
mainfrom
cursor/service-map-filtering-fc03
Draft

feat: Add Lucene/SQL search filter to Service Map page#2319
MikeShi42 wants to merge 4 commits into
mainfrom
cursor/service-map-filtering-fc03

Conversation

@MikeShi42
Copy link
Copy Markdown
Contributor

@MikeShi42 MikeShi42 commented May 20, 2026

Summary

Add support for filtering on Service Maps (HDX-3025). Two complementary filter mechanisms:

  1. Service name MultiSelect — A searchable, clearable dropdown populated with distinct service names from ClickHouse. Selecting services shows that service plus all its inbound callers and outbound callees — so you see the full neighborhood of the selected service(s) in the graph. The filter is applied post-JOIN on the outer query (WHERE serverServiceName IN (...) OR clientServiceName IN (...)), preserving the span linkage that builds edges.

  2. Lucene/SQL search bar — A free-form search input (same SearchWhereInput used on the Search page) for filtering on any span attribute. Supports both Lucene syntax and raw SQL WHERE clauses. This enables deeper filtering beyond service names (e.g. http.method:GET, Duration > 1000000, SpanAttributes['db.system'] = 'postgresql').

Both filters persist in URL params for shareable filtered views.

Key changes:

  • DBServiceMapPage.tsx — Added MultiSelect (service names via useGetKeyValues) and SearchWhereInput with URL state persistence via nuqs
  • ServiceMap.tsx — Thread where, whereLanguage, and serviceNames props through
  • useServiceMap.tsx — Apply service name filter on the outer query (post-JOIN) so both inbound and outbound neighbors are shown; apply free-text WHERE/filters via renderChartConfig in the CTEs

Screenshots or video

Full service map (no filter) — all 6 services visible:

Full service map

api-gateway selected — shows api-gateway + all neighbors (web-frontend, user-service, order-service, payment-service):

api-gateway with neighbors

order-service selected — shows order-service + api-gateway (inbound) + inventory-service (outbound):

order-service with neighbors

payment-service selected — shows payment-service + api-gateway (its caller):

payment-service with caller

Neighbor-inclusive filtering demo — selecting services and seeing their neighborhoods:

demo_neighbor_filtering.webm

Test results

Scenario Expected Actual
No filter 6 services 6 nodes
api-gateway api-gateway + 4 neighbors 5 nodes: api-gateway, web-frontend, user-service, order-service, payment-service
order-service order-service + 2 neighbors 3 nodes: order-service, api-gateway, inventory-service
payment-service payment-service + 1 neighbor 2 nodes: payment-service, api-gateway
user-service user-service + 1 neighbor 2 nodes: user-service, api-gateway
Lint + type check (make ci-lint) Pass Pass
Unit tests (make ci-unit) Pass Pass

How to test on Vercel preview

Preview routes: /service-map

Steps:

  1. Navigate to /service-map
  2. Verify a "All Services" MultiSelect dropdown and a Lucene/SQL search bar appear in the filter row
  3. Click the MultiSelect and select a service (e.g. "api-gateway")
  4. Verify the map shows the selected service AND its direct inbound/outbound neighbors with edges
  5. Add another service to the selection — verify the map expands to include that service's neighbors too
  6. Clear the selection — verify the map returns to showing all services
  7. Verify URL updates with services param for shareable links

References

  • Linear Issue: HDX-3025
  • Related PRs: None

To show artifacts inline, enable in settings.

Linear Issue: HDX-3025

Open in Web Open in Cursor 

Support filtering on Service Maps via a Lucene/SQL search bar on span data.

Changes:
- Add SearchWhereInput to DBServiceMapPage with Lucene/SQL toggle
- Thread where/whereLanguage through ServiceMap component to useServiceMap hook
- Pass user filters into both server and client span CTEs via renderChartConfig
- Include implicitColumnExpression from source for Lucene parsing support
- Store where/whereLanguage in URL params via nuqs for shareable links
- Include filter params in TanStack Query key for automatic refetching

Co-authored-by: Mike Shi <mike@hyperdx.io>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hyperdx-oss Ready Ready Preview, Comment May 22, 2026 4:23am

Request Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 20, 2026

⚠️ No Changeset found

Latest commit: eb50408

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 20, 2026

E2E Test Results

All tests passed • 179 passed • 3 skipped • 1246s

Status Count
✅ Passed 179
❌ Failed 0
⚠️ Flaky 3
⏭️ Skipped 3

Tests ran across 4 shards in parallel.

View full report →

Add a searchable MultiSelect dropdown that lets users filter the service
map by specific service names. The dropdown is populated with distinct
service names from the trace source via useGetKeyValues.

Changes:
- Add MultiSelect with service name options fetched from ClickHouse
- Wire selected services as SQL IN filter in useServiceMap's baseCTEConfig
- Persist selected services in URL via nuqs parseAsArrayOf for shareable links
- Place MultiSelect alongside SearchWhereInput in the filter bar
- Update SearchWhereInput placeholders to suggest attribute-level filters
  since service filtering is now handled by the dedicated dropdown

Co-authored-by: Mike Shi <mike@hyperdx.io>
SqlString.raw() returns an object for column identifiers - use '?' placeholder
(not '??') so it resolves to the raw string value correctly.

Co-authored-by: Mike Shi <mike@hyperdx.io>
Move the service name filter from the CTE level (span-level filtering)
to the outer query (post-JOIN filtering). The filter now matches edges
where either the server OR client service is in the selected set, so
selecting a service shows both its inbound callers and outbound callees
in the service graph.

Co-authored-by: Mike Shi <mike@hyperdx.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants