As a developer working with FHIR®, it’s important to understand the basics of FHIR search to retrieve specific resources from the server. FHIR search is a powerful tool that allows you to filter, sort, and paginate resources based on a variety of criteria. In this blog post, we will be exploring FHIR search, the different search operations available in FHIR, their syntax, and we will provide examples to help you better understand how to use them in your applications.
Note: The term [base] in this article refers to the server endpoint. E.g., in the Outburn HAPI-FIR server, the endpoint is http://hapi-fhir.outburn.co.il/fhir
Search Contexts in FHIR
Search operations in FHIR can be executed in one of three contexts, which control which set of resources are being searched:
1. Search across all resource types: This search context applies search parameters to all resource types. For example, a search for all resources with a “status” parameter of “active” would return all resources of any type that have a “status” parameter set to “active”. This context is useful when searching for a common parameter across all resource types or when the desired information’s resource type is unknown.
Example: Suppose we want to find all resources in the system with a ‘name’ parameter that contains the string “Smith”. We can use the following query, which will return Patients, Practitioners and Organizations with the “Smith” in the ‘name’ field:
GET [base]?name=Smith
2. Search a specified resource type: This search context applies search parameters only to a specific resource type. For example, suppose we want to search for all Patients that have a given name of “John” and a family name of “Doe”. We can use this search context to limit our search to only the Patient resources. We would achieve this like so:
GET [base]/Patient?given=John&family=Doe
3. A specified compartment: allow us to search for resources related to a specific patient or other resource in the system. A compartment is a group of related resources that can be searched together.
The syntax for a compartment search is:
GET [base]/[compartment]/[id]/[resource_type]?[search_params]
For example, to find all MedicationRequests associated with a Patient resource with the ID “789”, we would use:
GET [base]/Patient/789/MedicationRequest
Search Parameters
Search parameters are used to filter the resources returned by a search operation. They define the
criteria that must be met for a resource to be included in the search results.
There are several search parameters available in FHIR, each corresponding to a specific property of a resource. Some of the most commonly used search parameters include:
· _id: Searches for a resource with the specified logical id.
· status: Filters by the current status of a resource.
· code: Searches for a resource with the specified code or display name.
· subject: Filters by the patient or other subject associated with a resource.
· date: Filters by the date a resource was created or last modified.
Here are a couple of use cases:
· _id: To search for a patient with the ID “1234”, the search URL would be:
GET [base]/Patient?_id=1234
· code: To search for an observation with the LOINC code “8310-5” (Body temperature), the search URL would be:
GET [base]/Observation?code=8310-5
Modifiers
Modifiers can be used to refine the search results further. Modifiers are appended to search parameters and modify their behavior. FHIR supports several modifiers, including:
· _sort: used to specify the sort order of the results. Note: Each item in the comma-separated list is a search parameter, optionally with a ‘-‘ prefix. The prefix indicates decreasing order; in its absence, the parameter is applied in increasing order. Example: GET [base]/Observation?_sort=status,-date,category where the results will be displayed by a descending order.
· _count: used to limit the number of results returned.
· _summary: used to specify the level of summary information returned.
· _include: used to include resources that reference the searched resources.
· _revinclude: used to include resources that are referenced by the searched resources.
For example, to sort the results of a search for Patient resources by their family name, we can use the _sort modifier as follows:
GET [base]/Patient?_sort=family
Here’s an example of searching for all observations for a given patient and sorting them by date:
GET [base]/Observation?subject=Patient/123&_sort=date
To limit the number of results returned, we can use the _count modifier as follows:
GET [base]/Patient?_count=10
To include resources that reference the searched resources, we can use the _include modifier as follows:
GET [base]/Observation?subject:Patient=[patient_id]&_include=Observation:encounter
This search returns all Observation resources for a given patient and includes any Encounter resources that reference the Observation resources.
To include resources that are referenced by the searched resources, we can use the _revinclude modifier as follows:
GET [base]/DiagnosticReport?subject=Patient/123&_revinclude=DiagnosticReport:subject
This would search for all the DiagnosticReport resources where the subject reference matches Patient/123, and include the corresponding Patient resource in the search results.
To specify the level of summary information returned, we can use the _summary modifier as follows:
GET [base]/Patient?_summary=data
This search returns only the data elements of the Patient resource, excluding any text or narrative elements.
_elements modifier
The _elements parameter allows you to control which elements of a resource should be returned in the search results. It is used to restrict the set of elements returned in the search response to only those that you are interested in, by specifying a comma-separated list of element names. You can also use it to exclude specific elements by prefixing the element name with a minus sign (“-“). For example:
GET [base]/Patient?_elements=name,birthDate
This search will return a list of patients, but only with the name and birthDate elements included in the response.
Complex queries
Modifiers can also be combined to create more complex search queries. For example, to search for Observation resources for a given patient and code and sort the results by date, we can use the following query:
GET [base]/Observation?subject=Patient/[patient_id]&code=[code]&_sort=date
In this query, we have used the subject parameter to specify the patient and the code parameter to specify the code we are interested in. We have also used the _sort modifier to sort the results by date.
Takeaways
-
- FHIR search is based on RESTful principles and uses a URL syntax to define the search operation.
-
- Search parameters are used to filter the search results and can be combined using Boolean operators to create complex queries.
-
- Modifiers are used to refine the search results and can be used to control sorting and pagination.
Final note: Bear in mind that this is not a comprehensive guide. Check out the FHIR search specs for more information.
New to FHIR? Check out our piece on profiling, as a next logical step