Skip to content

feat: EHR search table stakes (_has, uri, include wildcards, 2-hop chains) - #51

Draft
degoke wants to merge 1 commit into
mainfrom
degoke/search-ehr-apps-86c6
Draft

degoke wants to merge 1 commit into
mainfrom
degoke/search-ehr-apps-86c6

Conversation

@degoke

@degoke degoke commented Sep 19, 2026

Copy link
Copy Markdown
Owner

Implement the search features EHR apps actually send, instead of Lucene or _filter first. This is item 2 of the HAPI-inspired build list (REST table stakes is PR #50).

What landed

_has reverse chaining. Patient?_has:Observation:subject:code=8867-4 uses the existing search parser/planner/executor. One extra nested _has is allowed; deeper nesting is still ErrUnsupportedFeature.

uri SearchParameters. Registry uri params are indexed as uri.* (stored on the string tables). Exact match plus :below / :above hierarchy modifiers.

Include wildcards. _include=Observation:*, _include=*:*, _revinclude=Observation:*, and _revinclude=*:* expand at resolve time to the matching reference SearchParameters. Source * on _include means the search type (*:general-practitioner on Patient → Patient:general-practitioner). Typed includes _include=Observation:subject:Patient work. Recursive _include:iterate is still rejected.

Two-hop chains. Observation?subject.organization.name=Acme parses as a nested ChainClause, walks the inner match first, then the outer reference. Depth > 2 stays unsupported.

Execution notes

  • _has and two-hop chains run on SearchQueryExecutor (SQLite/mem + Postgres).
  • Wildcard _include / _revinclude still need SearchAdvancedExecutor (Postgres-first), same as existing includes.
  • Wildcard expansion skips reference params whose target types are not enabled, rather than failing the whole query.

Tests

  • Parser/resolve/execute coverage in pkg/search/ehr_search_test.go
  • Indexer emits uri.url for Questionnaire
  • Postgres integration tests for _has, two-hop, url:below, and Observation:* (skipped without Postgres)
Open in Web Open in Cursor 

…ains)

Implement the search features EHR apps actually send, rather than Lucene or
_filter first:

- Reverse chaining via _has:Type:ref:param (one nested _has)
- uri SearchParameters with :below / :above, indexed as uri.*
- _include / _revinclude wildcards (ResourceType:* and *:*)
- Two-hop chained search (e.g. subject.organization.name)

Recursive _include:iterate and chain depth > 2 stay unsupported.

Co-authored-by: Adegoke Adewoye <[email protected]>
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