Skip to content

Implement metadata-filtered document + event queries (#4791)#4792

Merged
jeremydmiller merged 2 commits into
masterfrom
feat/4791-metadata-filtered-queries
Jun 27, 2026
Merged

Implement metadata-filtered document + event queries (#4791)#4792
jeremydmiller merged 2 commits into
masterfrom
feat/4791-metadata-filtered-queries

Conversation

@jeremydmiller

Copy link
Copy Markdown
Member

Summary

  • Implements the three new exact-match metadata filters from JasperFx.Events 2.18.0's DocumentQueryOptions / EventQuery (jasperfx/CritterWatch#629).
  • DocumentsDocumentStore.DocumentDiagnostics.cs extends the existing SQL builder (already conjoining id::text = @id + tenant_id = @tenant) with correlation_id, causation_id, last_modified_by WHERE clauses. Each filter is honored only when (a) the option is set AND (b) the document mapping has the corresponding metadata column enabled — emitting a WHERE on a column the table doesn't have would throw 42703 undefined_column.
  • EventsQueryEventStore.cs extends the LINQ predicate chain with CorrelationId / CausationId / UserName Where clauses, gated on EventGraph.Metadata.X.Enabled (mirrors the gate in EventQueryMapping.cs:46-59 that conditionally registers the queryable member).
  • When a filter is set but the column is disabled the filter is silently skipped (per the JasperFx contract: "Only honored when the store advertises and captures the metadata column; otherwise ignored").
  • Bumps JasperFx + JasperFx.Events + both source generators 2.17.0 → 2.18.0.

Test plan

Tests land in DocumentDbTests/Metadata — 28 tests total, all green on net10.

Seeding strategy: each suite seeds 8 docs / 8 events whose metadata cover every combination of corr ∈ {c0, c1} × caus ∈ {u0, u1} × lmb/user ∈ {b0|n0, b1|n1}, indexed 0..7 by the binary tuple. Each filter combo's expected subset is then a precise list of indices.

document_diagnostics_metadata_filter_tests.cs — 14 tests

  • every_filter_combo_returns_the_expected_subset Theory — 8 cases walking every (corr × caus × lmb) on/off permutation
  • filter_on_an_unmatched_value_returns_zero_rows
  • filter_is_silently_ignored_when_correlation_id_column_is_disabled
  • filter_is_silently_ignored_when_causation_id_column_is_disabled
  • filter_is_silently_ignored_when_last_modified_by_column_is_disabled
  • filter_set_alongside_an_enabled_filter_when_a_column_is_disabled_still_narrows_via_the_enabled_one
  • IdEquals_and_metadata_filters_compose_with_AND

event_diagnostics_metadata_filter_tests.cs — 14 tests

Same 8-event matrix + 6 targeted Facts mirroring the doc-side shape, plus a compose-with-EventTypeName regression guard.

  • All 28 new tests green locally
  • Existing document_store_diagnostics_tests (CoreTests, 9 tests) still green
  • CI matrix (PG 15/latest × net8/net10 × Newtonsoft/STJ)

Notes

  • Deferred per the issue's v1 scope: headers JSON containment + timestamp ranges.

Closes #4791

🤖 Generated with Claude Code

jeremydmiller and others added 2 commits June 27, 2026 08:58
Adds the three new exact-match metadata filters from JasperFx.Events 2.18.0's
DocumentQueryOptions / EventQuery (JasperFx/CritterWatch#629):

- IDocumentStoreDiagnostics.QueryDocumentsAsync — extends the SQL builder
  (already conjoining id::text + tenant_id) with correlation_id,
  causation_id, last_modified_by WHERE clauses. Each filter is honored
  only when both the option is set AND the document mapping has the
  corresponding metadata column enabled — emitting a WHERE on a column
  the table doesn't have would throw 42703 undefined_column.
- IReadOnlyEventStore.QueryEventsAsync — extends the LINQ predicate
  chain with CorrelationId / CausationId / UserName Where clauses,
  gated on EventGraph.Metadata.X.Enabled (mirrors the gate in
  EventQueryMapping that conditionally registers the queryable member).

When a filter is set but the column is disabled the filter is silently
skipped (per the JasperFx contract: "Only honored when the store
advertises and captures the metadata column; otherwise ignored").

Bumps JasperFx + JasperFx.Events + both source generators 2.17.0 → 2.18.0.

Test coverage in DocumentDbTests/Metadata (28 tests, all green on net10):

- document_diagnostics_metadata_filter_tests (14 tests):
  * Theory: every_filter_combo_returns_the_expected_subset — 8 cases
    walking every (corr × caus × lmb) on/off permutation. Seeds 8 docs
    covering every (c0|c1, u0|u1, b0|b1) combination so each Theory row
    asserts a precise subset.
  * Targeted Facts for column-disabled silent-ignore (one per filter).
  * Mixed scenario: enabled + disabled filters compose correctly.
  * IdEquals + metadata filters compose with AND.
  * Unmatched-value returns zero rows.

- event_diagnostics_metadata_filter_tests (14 tests): same 8-event matrix
  + 6 targeted Facts mirroring the doc-side shape, plus a compose-with-
  EventTypeName regression guard.

Closes #4791

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jeremydmiller
jeremydmiller merged commit e2ec0ad into master Jun 27, 2026
9 checks passed
@jeremydmiller
jeremydmiller deleted the feat/4791-metadata-filtered-queries branch June 27, 2026 15:51
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.

Implement metadata-filtered document + event queries (QueryDocumentsAsync / QueryEventsAsync WHERE clauses)

1 participant