Search Parameters
OctoFHIR supports comprehensive FHIR search capabilities including all standard modifiers, date prefixes, and advanced features like _include and _revinclude.
Basic Search
Section titled “Basic Search”Search for resources using query parameters:
# Search for patients by family nameGET /Patient?family=Smith
# Search with multiple parameters (AND logic)GET /Patient?family=Smith&gender=female
# Search with multiple values (OR logic)GET /Patient?family=Smith,JohnsonString Modifiers
Section titled “String Modifiers”String search parameters support the following modifiers:
Default (starts-with)
Section titled “Default (starts-with)”# Matches "Smith", "Smithson", "Smithfield"GET /Patient?family=Smith:exact
Section titled “:exact”Case-sensitive exact match:
# Matches only "Smith" (not "smith" or "SMITH")GET /Patient?family:exact=Smith:contains
Section titled “:contains”Substring match anywhere in the value:
# Matches "Smith", "Blacksmith", "Smithson"GET /Patient?family:contains=mit:missing
Section titled “:missing”Find resources where the element is present or absent:
# Patients without an identifierGET /Patient?identifier:missing=true
# Patients with at least one identifierGET /Patient?identifier:missing=falseToken Modifiers
Section titled “Token Modifiers”Token search parameters (for codes, identifiers, etc.) support:
System|Code Format
Section titled “System|Code Format”# Search by system and codeGET /Patient?identifier=http://hospital.org/mrn|MRN-001
# Search by code only (any system)GET /Patient?identifier=MRN-001
# Search by system only (any code)GET /Patient?identifier=http://hospital.org/mrn|Search by display text rather than code:
# Find observations where code display contains "blood pressure"GET /Observation?code:text=blood pressureExclude resources with matching codes:
# Patients that are NOT maleGET /Patient?gender:not=male:of-type
Section titled “:of-type”For Identifier searches, match by identifier type:
# Find patients by MRN type identifierGET /Patient?identifier:of-type=http://terminology.hl7.org/CodeSystem/v2-0203|MRDate Prefixes
Section titled “Date Prefixes”Date search parameters support precision-aware comparisons:
| Prefix | Meaning | Example |
|---|---|---|
eq | Equal (default) | birthdate=eq1980-01-15 |
ne | Not equal | birthdate=ne1980-01-15 |
lt | Less than | birthdate=lt1990-01-01 |
le | Less than or equal | birthdate=le1990-01-01 |
gt | Greater than | birthdate=gt1980-01-01 |
ge | Greater than or equal | birthdate=ge1980-01-01 |
sa | Starts after | date=sa2024-01-01 |
eb | Ends before | date=eb2024-12-31 |
ap | Approximately | date=ap2024-06-15 |
Date Ranges
Section titled “Date Ranges”Combine prefixes to search within ranges:
# Patients born in the 1980sGET /Patient?birthdate=ge1980-01-01&birthdate=lt1990-01-01
# Observations from January 2024GET /Observation?date=ge2024-01-01&date=lt2024-02-01Date Precision
Section titled “Date Precision”Dates match at their precision level:
# Matches any date in 1980GET /Patient?birthdate=1980
# Matches any date in January 1980GET /Patient?birthdate=1980-01
# Matches exactly January 15, 1980GET /Patient?birthdate=1980-01-15Include and RevInclude
Section titled “Include and RevInclude”_include
Section titled “_include”Include referenced resources in the response:
# Search observations and include referenced PatientGET /Observation?code=8867-4&_include=Observation:subject
# Include multiple reference typesGET /Observation?_include=Observation:subject&_include=Observation:performer_revinclude
Section titled “_revinclude”Include resources that reference the search results:
# Search patients and include their observationsGET /Patient?_revinclude=Observation:subject
# Include multiple reverse referencesGET /Patient?_revinclude=Observation:subject&_revinclude=Condition:subject:iterate
Section titled “:iterate”For recursive includes (follow reference chains):
# Include subject and the subject's organizationGET /Observation?_include=Observation:subject&_include:iterate=Patient:organizationResult Filtering
Section titled “Result Filtering”_elements
Section titled “_elements”Return only specific elements:
# Return only id, name, and birthDateGET /Patient?_elements=id,name,birthDateResources returned with _elements are tagged with SUBSETTED in their meta.
_summary
Section titled “_summary”Return summarized resources:
| Value | Description |
|---|---|
true | Return summary elements only |
false | Return full resources (default) |
text | Return text, id, meta, and mandatory elements |
data | Return data elements only (no text) |
count | Return only the count, no entries |
# Get summary viewGET /Patient?_summary=true
# Get just the countGET /Patient?_summary=countPagination
Section titled “Pagination”_count
Section titled “_count”Limit the number of results:
# Return first 10 resultsGET /Patient?_count=10Page Navigation
Section titled “Page Navigation”Use the link elements in the Bundle response:
{ "resourceType": "Bundle", "type": "searchset", "total": 100, "link": [ {"relation": "self", "url": "..."}, {"relation": "next", "url": "...?_page=2"}, {"relation": "previous", "url": "...?_page=0"} ]}Sorting
Section titled “Sorting”Sort results by one or more parameters:
# Sort by birthDate ascendingGET /Patient?_sort=birthdate
# Sort by birthDate descendingGET /Patient?_sort=-birthdate
# Sort by multiple fieldsGET /Patient?_sort=family,-birthdateComposite Search Parameters
Section titled “Composite Search Parameters”Search using composite parameters that combine multiple values:
# Search by code AND value (composite parameter)GET /Observation?code-value-quantity=http://loinc.org|8867-4$gt60Chained Search
Section titled “Chained Search”Search by properties of referenced resources:
# Observations for patients named "Smith"GET /Observation?subject:Patient.family=Smith
# Observations for patients born after 1980GET /Observation?subject:Patient.birthdate=gt1980-01-01Common Search Parameters
Section titled “Common Search Parameters”These parameters work on all resource types:
| Parameter | Type | Description |
|---|---|---|
_id | token | Resource logical ID |
_lastUpdated | date | When the resource was last updated |
_profile | uri | Profiles the resource claims to conform to |
_tag | token | Tags applied to the resource |
_security | token | Security labels on the resource |
_source | uri | Source URI for the resource |
Examples
Section titled “Examples”Complex Patient Search
Section titled “Complex Patient Search”# Active female patients named Smith, born in the 1980s,# sorted by birthdate, returning only id and nameGET /Patient?family=Smith&gender=female&active=true&birthdate=ge1980-01-01&birthdate=lt1990-01-01&_sort=birthdate&_elements=id,nameObservation Search with Includes
Section titled “Observation Search with Includes”# Final observations with heart rate code,# include the patient, return first 20GET /Observation?status=final&code=http://loinc.org|8867-4&_include=Observation:subject&_count=20Find Missing Data
Section titled “Find Missing Data”# Patients without phone numbersGET /Patient?telecom:missing=true
# Observations without valuesGET /Observation?value-quantity:missing=trueCustom Search Parameters
Section titled “Custom Search Parameters”OctoFHIR supports creating custom SearchParameter resources that are automatically registered and immediately available for search operations.
Creating Custom Search Parameters
Section titled “Creating Custom Search Parameters”Custom search parameters can be created in two ways:
- Via FHIR Packages - Include SearchParameter resources in your Implementation Guide
- Via REST API - Create SearchParameter resources directly through the FHIR API
REST API Creation
Section titled “REST API Creation”Create a SearchParameter resource using the standard FHIR create operation:
POST /fhir/SearchParameterContent-Type: application/fhir+json
{ "resourceType": "SearchParameter", "url": "http://example.org/SearchParameter/patient-custom-field", "name": "PatientCustomField", "code": "custom-field", "status": "active", "description": "Search by custom patient field", "base": ["Patient"], "type": "string", "expression": "Patient.extension.where(url='http://example.org/custom-field').valueString"}Response:
{ "resourceType": "SearchParameter", "id": "12345", "meta": { "versionId": "1", "lastUpdated": "2025-01-02T10:30:00Z" }, "url": "http://example.org/SearchParameter/patient-custom-field", "code": "custom-field", ...}Automatic Registration
Section titled “Automatic Registration”When you create, update, or delete a SearchParameter resource:
- FHIRPath Validation - The expression is validated for syntax correctness
- Immediate Registration - The parameter is registered in the search registry
- Zero Downtime - Available immediately without server restart
- Lock-Free - No impact on concurrent search operations
# Create the SearchParameterPOST /fhir/SearchParameter { ... }
# Immediately use it in search (no restart needed!)GET /fhir/Patient?custom-field=some-valueFHIRPath Expression Validation
Section titled “FHIRPath Expression Validation”Invalid FHIRPath expressions are rejected:
POST /fhir/SearchParameter{ "resourceType": "SearchParameter", "expression": "Patient..invalid..syntax", # Invalid! ...}Response (400 Bad Request):
{ "resourceType": "OperationOutcome", "issue": [{ "severity": "error", "code": "invalid", "diagnostics": "Invalid FHIRPath expression: unexpected token" }]}SearchParameter Fields
Section titled “SearchParameter Fields”Required fields:
code- The search parameter name (used in queries)url- Canonical URL (must be unique)type- Parameter type:string,token,reference,date,number,quantity,uri,composite,specialbase- Resource types this parameter applies to (array)
Optional but recommended:
expression- FHIRPath expression defining what to searchdescription- Human-readable descriptionmodifier- Supported modifiers (:exact,:contains, etc.)comparator- Supported comparators for numbers/dates (eq,gt,lt, etc.)target- Target resource types (forreferencetype parameters)
Examples
Section titled “Examples”Extension Search Parameter
Section titled “Extension Search Parameter”Search by extension values:
{ "resourceType": "SearchParameter", "url": "http://example.org/SearchParameter/patient-ethnicity", "code": "ethnicity", "type": "token", "base": ["Patient"], "expression": "Patient.extension.where(url='http://example.org/ethnicity').valueCoding"}Usage:
GET /fhir/Patient?ethnicity=http://example.org/ethnicity-codes|hispanicNested Field Search
Section titled “Nested Field Search”Search by nested fields:
{ "resourceType": "SearchParameter", "url": "http://example.org/SearchParameter/patient-home-city", "code": "home-city", "type": "string", "base": ["Patient"], "expression": "Patient.address.where(use='home').city"}Usage:
GET /fhir/Patient?home-city=BostonMulti-Resource Parameter
Section titled “Multi-Resource Parameter”Apply the same parameter to multiple resource types:
{ "resourceType": "SearchParameter", "url": "http://example.org/SearchParameter/clinical-custom-status", "code": "custom-status", "type": "token", "base": ["Observation", "Condition", "Procedure"], "expression": "%resource.extension.where(url='http://example.org/custom-status').valueCode"}Usage:
GET /fhir/Observation?custom-status=reviewedGET /fhir/Condition?custom-status=reviewedGET /fhir/Procedure?custom-status=reviewedReference Search Parameter
Section titled “Reference Search Parameter”Search by custom references:
{ "resourceType": "SearchParameter", "url": "http://example.org/SearchParameter/observation-custom-performer", "code": "custom-performer", "type": "reference", "base": ["Observation"], "target": ["Practitioner", "Organization"], "expression": "Observation.extension.where(url='http://example.org/custom-performer').valueReference"}Usage:
GET /fhir/Observation?custom-performer=Practitioner/12345Updating Search Parameters
Section titled “Updating Search Parameters”Update a SearchParameter to modify its behavior:
PUT /fhir/SearchParameter/12345{ "resourceType": "SearchParameter", "id": "12345", "url": "http://example.org/SearchParameter/patient-custom-field", "code": "custom-field", "type": "string", "base": ["Patient"], "expression": "Patient.extension.where(url='http://example.org/updated-field').valueString", "modifier": ["exact", "contains"] # Added modifiers}The updated parameter is immediately available with new behavior.
Deleting Search Parameters
Section titled “Deleting Search Parameters”Delete a SearchParameter when no longer needed:
DELETE /fhir/SearchParameter/12345After deletion:
- The parameter is removed from the search registry
- Queries using this parameter will fail with “unknown search parameter” error
- Existing data is unchanged (only the search capability is removed)
Performance Characteristics
Section titled “Performance Characteristics”OctoFHIR’s search parameter architecture is designed for high-performance production workloads:
Lock-Free Reads:
- Search queries never block on registry access
- Single atomic load (~1-5 nanoseconds)
- Zero contention during concurrent searches
Incremental Updates:
- SearchParameter CRUD operations update registry incrementally
- No full registry reload needed
- Update time: ~100-500 nanoseconds
Query Cache:
- Automatically cleared when parameters change
- Prevents stale query results
- Minimal performance impact
Multi-Instance Deployments
Section titled “Multi-Instance Deployments”Best Practices
Section titled “Best Practices”- Use Canonical URLs - Follow URI naming conventions (e.g.,
http://your-org.org/SearchParameter/name) - Test FHIRPath Expressions - Validate expressions work correctly before deployment
- Document Custom Parameters - Add clear descriptions and examples
- Version Your Parameters - Include version in URL when making breaking changes
- Use Packages for Production - Package-based parameters ensure consistency across instances
Limitations
Section titled “Limitations”- No Semantic Validation - FHIRPath expressions are checked for syntax, not semantics
- No Runtime Type Checking - Expression type mismatches fail gracefully at query time
- Extension-Only - Custom parameters typically target extensions (core FHIR fields already have parameters)
Troubleshooting
Section titled “Troubleshooting”Parameter not found:
GET /fhir/Patient?my-param=value# Error: Unknown search parameter 'my-param'- Verify SearchParameter was created successfully
- Check the
codefield matches the query parameter name - Ensure
baseincludes the resource type you’re querying
No results with valid parameter:
GET /fhir/Patient?custom-field=value# Returns empty Bundle- Verify the FHIRPath expression matches your data structure
- Check extension URLs match exactly (case-sensitive)
- Test the expression against sample resources
Invalid expression error:
POST /fhir/SearchParameter# Error: Invalid FHIRPath expression- Review FHIRPath syntax
- Use parentheses for complex expressions
- Test expression with FHIRPath evaluator tools