Implementation Features
| Feature | Support | Notes |
|---|---|---|
| System-level Search | ✅ Full | Requires _type parameter |
| Type-level Search | ✅ Full | Primary search form |
| Compartment Search | ✅ Full | Supports specific type or all types (*) |
| GET Search | ✅ Full | Query string parameters |
| POST Search | ✅ Full | Form-urlencoded body |
| Parameter Types | ✅ Full | string, token, date, number, quantity, reference, uri, text, content |
| Value Prefixes | ✅ Full | eq ne gt lt ge le sa eb ap for date/number/quantity/_lastUpdated |
| Modifiers | ⚠️ Partial | Implemented subset; validated per type + SearchParameter metadata |
| Special Parameters | ✅ Full | _id, _lastUpdated, _in, _list, _text, _content |
| Chaining | ✅ Single-level | subject.name=peter, subject:Patient.name=peter |
Reverse chaining (_has) | ✅ Full | _has:Observation:subject:code=... |
| Membership Search | ✅ Full | _in and _list parameters |
_include / _revinclude | ✅ Full | Wildcards (*, Resource:*), :iterate (depth-limited) |
_filter (R5-style) | ✅ Full | Expression-based filtering with multiple operators |
| Pagination | ✅ Cursor-based | Keyset pagination with _cursor and _cursor_direction |
| Totals | ✅ Full | _total=accurate, _total=estimate, _total=none |
| Summary Modes | ✅ Full | _summary=count, _summary=text, _summary=data, _summary=true |
_elements | ✅ Full | Element filtering (when _summary not specified) |
| Sorting | ⚠️ Limited | Only _id and _lastUpdated supported |
| Unknown Parameters | ✅ Lenient | Ignored by default; strict mode via Prefer: handling=strict |
| Composite Parameters | ❌ Not Supported | Future work |
Endpoints TLQ FHIR implements
| Scope | GET | POST | Notes |
|---|---|---|---|
| System-level | /fhir/?_type=A,B | /fhir/_search | _type is required |
| Type-level | /fhir/{resourceType}?… | /fhir/{resourceType}/_search | Primary search form |
| Compartment | /fhir/{Compartment}/{id}/{type} | /fhir/{Compartment}/{id}/{type}/_search | “All types” uses literal * |
POST-based search must use
Content-Type: application/x-www-form-urlencoded.
TLQ FHIR merges query string parameters and body parameters into one ordered
parameter list.Parameter occurrence semantics (AND/OR)
TLQ FHIR preserves parameter occurrences in request order (no lossy map parsing):- Repeating a parameter is AND:
name=John&name=Smith - Comma-separated values are OR:
name=John,Smith
Search syntax (modifiers, prefixes, chaining)
Parameter name forms
Most resource parameters follow::{modifier}is case-insensitive (except reference type modifiers like:Patient).{chain}is single-level chaining (see below)
Value prefixes
TLQ supports the standard FHIR prefixes when they appear at the start of the value. Applies to:date, number, quantity, and _lastUpdated.
| Prefix | Meaning (FHIR-style) | Examples |
|---|---|---|
eq | equal (default if omitted) | birthdate=eq1990-01-01 |
ne | not equal | value=ne5 |
gt | greater than | value=gt5 |
ge | greater or equal | date=ge2024-01-01 |
lt | less than | date=lt2024-02 |
le | less or equal | value=le10 |
sa | starts after | date=sa2024-01-01 |
eb | ends before | date=eb2024-01-01 |
ap | approximately (±10%, min 1 day for dates) | date=ap2024-01, value=ap100.0 |
- Date precision is range-based (
2024matches any date in 2024;2024-01matches any date in Jan 2024). - For
number/quantity,eq/nerespect implied precision (FHIR-style decimal ranges).
Modifiers
TLQ recognizes and validates a subset of FHIR modifiers. A modifier must:- Be valid for the parameter type, and
- Be allowed by the underlying
SearchParametermetadata (when provided)
:missing | most indexed parameter types | existence check (true = missing, false = present) |
| :exact | string, _text, _content | exact match / phrase search |
| :contains | string, uri, some reference | substring match (string/uri); hierarchy closure (reference) |
| :text | string, token, reference | text match against human text fields (value/display) |
| :code-text | token, reference | match code/id-like parts (case-insensitive starts-with) |
| :text-advanced | token, reference | PostgreSQL full-text (websearch_to_tsquery) on display |
| :not | token, _in, _list | negation (token set semantics; membership exclusion) |
| :identifier | reference | token-style match against Reference.identifier |
| :above / :below | reference, uri | hierarchy traversal (reference) / URL path ancestry |
| :of-type | token | Identifier triple typeSystem | typeCode | value match |
| :{ResourceType} | reference | reference type restriction (e.g. subject:Patient=123) |
Examples:
Token modifiers
:in, :not-in, :above, and :below are rejected
(terminology-backed behavior is not implemented yet).Chaining (single-level)
TLQ supports single-level chaining on reference parameters:- Basic chaining:
subject.name=peter - Type-restricted chaining:
subject:Patient.name=peter
Reverse chaining (_has)
TLQ supports _has (reverse chaining) with the form:
What is searchable?
Resources become searchable through SearchParameter resources that define:- What to index: FHIRPath expressions extract values from resources
- How to search: Parameter types determine search semantics
- Where to store: Each type maps to a dedicated database table
Parameter types and tables
| Type | Database Table | Example Values |
|---|---|---|
string | search_string | name=John, name:contains=doe |
token | search_token | status=active, code=12345 |
date | search_date | birthdate=2020-01-01, date=ge2020 |
number | search_number | value=5.0, value=lt5.1 |
quantity | search_quantity | height=170, height=ge170 |
reference | search_reference | subject=Patient/123, subject.name=peter |
uri | search_uri | url=http://example.com, url:below=... |
text | search_text | _text=diabetes |
content | search_content | _content=diabetes |
composite | search_composite | Not yet supported |
Token and quantity parameters also support pipe-delimited forms:
system|code
(token), and number||code / number|system|code (quantity).Unknown or unsupported parameters
By default, TLQ FHIR follows the common “lenient” behavior and ignores unknown/unsupported search parameters. If you want strict validation, usePrefer: handling=strict:
Advanced search features supported
_include / _revinclude
TLQ FHIR supports _include and _revinclude including:
- Wildcards (
*,Resource:*) :iterate(depth-limited to prevent infinite recursion)- Deduplication of included resources
Membership search: _in and _list
TLQ FHIR supports membership searches (e.g. “resources in Group/List”):
_filter (FHIR R5-style expression filter)
TLQ FHIR supports _filter expressions for type-level search (and for system search when a single
type is implied).
Operators supported include: eq, ne, co, sw, ew, re, gt, lt, ge, le, sa,
eb, ap, pr, in, ni, ss, sb.
Example (use --data-urlencode so spaces and quotes are encoded correctly):
_filter does not support modifiers (_filter:...) and should not be
combined with multi-type system searches. Prefer a type-level search when
using _filter.Pagination (cursor-based)
TLQ FHIR uses keyset/cursor pagination for stable paging over a changing dataset.- Control page size with
_count - Follow
Bundle.linkURLs (next,prev,first,last) returned by the server - Paging links use TLQ FHIR’s internal parameters:
_cursor: base64url-encodedlastUpdated,id_cursor_direction:next,prev, orlast
TLQ FHIR parses
_offset but does not use it for paging. Pagination links
will not include _offset.Totals and response shaping
_total
TLQ FHIR calculates totals when requested via _total:
_total=accurate: compute an exactBundle.total_total=estimate: allow faster, estimated totals (where possible)_total=none: omit totals entirely
_summary and _elements
TLQ FHIR applies _summary / _elements filtering to Bundle.entry[].resource:
_summary=countshort-circuits fetching resources and returns only the count bundle_summarytakes precedence over_elements- Includes are suppressed for
_summary=text(common server behavior)
Limits and configuration knobs
Search limits are configurable underfhir.search:
max_count(default1000): maximum allowed_countmax_total_results(default10000): maximum allowed_maxresultsmax_includes(default10): maximum number of_include+_revincludemax_include_depth(default3): maximum:iteratedepthenable_text/enable_content: enable_text/_contentfull-text search parameters
Known gaps
Current limitations in TLQ FHIR’s search engine:- Recursive chaining (e.g.
subject.organization.name) is not supported (single-level only) - Composite search parameters are not supported