This page discusses how to use a FHIR endpoint to search for and fetch data. We will enter simple FHIR search queries into the address bar of a web browser.
In many ways, the search functionality in FHIR is one of the nicest features for your developers to use. Using a simple RESTful syntax, you can construct both simple and very complex queries, and find all kinds of data in a consistent way.
The mechanics of a FHIR search query are simple:
GET [baseUrl]/[resourceType]?[optional parameters]
.This page will give you a taste of the various ways you can search for data. To learn more, visit the FHIR Search page.
The most basic form of a search is a search with no parameters, which matches all resources of a given type. For example, the following search returns all Patients in the system:
http://localhost:8000/Patient
You may notice that the response to this query only returns a small number of Patient resources (by default, 50). This is because the server is only returning the first page of results in its initial response. See paging search results below for information about how to fetch subsequent pages.
You can add parameters that narrow your search. The following search query finds any patients with family name "Smith". In this example, we're using the name
search parameter. You can find a list of all of the default search parameters in the Search Parameters section at the bottom of the FHIR Patient page.
http://localhost:8000/Patient
Combine multiple parameters to narrow your search even further (multiple parameters are interpreted as an AND combination).
http://localhost:8000/Patient
Comma-separated values are treated as an OR search (either value may match). For example, the following search query finds people with family name "smith" and a given name of either "stevie" or "elisha".
http://localhost:8000/Patient
To search Observation resources for lab tests, we have a few options. First, let's use the laboratory
category to find all lab tests. For example, the following search query finds all lab tests for the given patient:
http://localhost:8000/Observation
If you want to find a specific lab test, you can use the LOINC code for that test and the code
search parameter. For example, the following search query finds all Potassium tests (LOINC code 6298-4) across all patients:
http://localhost:8000/Observation
We can also add a value-quantity
search parameter to find Potassium tests with a specific value. In this example, we're searching for any Potassium tests with a value below 4.0 mmol/L:
http://localhost:8000/Observation
Searching by date in FHIR is quite powerful. Let's start with a simple demonstration. If you want to search for anything matching a date, simply use that date as the search parameter value. For example, here is a search query for any Patients with a given birthday:
http://localhost:8000/Patient
Partial dates are okay, too, and they will match any values within the part. For example, the following search finds any Patients born in 1941:
http://localhost:8000/Patient
Date searches also support a set of qualifiers, which are prefixes on the date that act as a comparator. For example, the value ge2011-01-01
matches any date on or after 2011-01-01. A number of other qualifiers are available under the Date section of the FHIR Search page.
The following search query matches any Encounters for the given patient that started or ended between June 2009 and July 2009.
http://localhost:8000/Encounter
FHIR also supports a special parameter called _lastUpdated
that can be used on any resource type. This parameter filters search results to only match resources that were last updated at or after the given date/time (or optionally before).
If the _lastUpdated
parameter is specified with a date and time but no timezone, then the server default timezone will be used. If a date value is specified without a time, the search will return resources that have a last updated date that matches the specified date in at least one timezone. For example, if a Patient resource was last updated in Sidney, Australia at 8am, April 15th, 2021, Australia Eastern Standard Time (AEST), then a search for either _lastUpdated=2021-04-15
or _lastUpdated=2021-04-14
will return the Patient resource because 8am on April 15th in AEST timezone would also be 6pm on April 14th in Eastern Daylight timezone.
The _lastUpdated
parameter considers the value found in Resource.meta.lastUpdated
. It is important to remember that this value is always provided by the server, and clients do not have any control over a resource's last updated date.
To find any Patient resources updated on or after midnight on Jan 1 2017, use the following URL:
http://localhost:8000/Patient
When returning search results, the server will page them by default. Consider the following search query:
http://localhost:8000/Observation
This returns a Bundle beginning with the following:
{
"resourceType": "Bundle",
"type": "searchset",
"total": 156,
"link": [
{
"relation": "self",
"url": "http://localhost:8000/Observation?code=http://loinc.org|6298-4"
},
{
"relation": "next",
"url": "http://localhost:8000?_getpages=c18f6abf-16e3-41b1-a65b-081b2f6a9642&_getpagesoffset=10&_count=10&_pretty=true&_bundletype=searchset"
}
],
(...more...)
}
Here we can see that there are 156 matching search results in total. However, the Bundle will only actually contain the first page of results. The URL marked next
provides a link to fetch the next page of results. This allows client applications to fetch data in manageable amounts, which improves performance in many cases.
You can control the number of returned results by using the _count
parameter:
http://localhost:8000/Observation
In the bundle shown above, the total
element indicates the full number of available search results.
On a real server this element may or may not be present in your search results. By default, the server will populate this element if it knows the total number of elements that match the given search, but will not populate it if it has not yet determined how many results are matching. For example, if you are searching for Patient?name=smith
this might match many thousands of results. The server will return the first page of these results, but it is a potentially slow operation to actually count the remaining results so the server avoids this delay and returns the first page right away.
A client can influence this behaviour by adding an additional _total
parameter to your search, e.g.
http://localhost:8000/Observation
Be warned, forcing the total to be calculated may cause performance issues! The cost of calculating an accurate total count grows as your data grows, so using this parameter may cause your application to behave well initially, but become unusable as the total amount of data grows. This is especially true for more complex queries. If you are designing a UI with a search results pager, it is often an antipattern to design it in a way that requires an accurate count.
FHIR makes it easy to sort the results of your search query according to whatever criteria you require.
To sort, simply add the _sort
parameter followed by the name of a search parameter. Note that this needs to be the name of a search parameter and not the name of an element in the resource; these are often but not always the same thing.
For example, to search for Patients sorted by family name (ascending and descending shown):
http://localhost:8000/Patient
http://localhost:8000/Patient
You can also sort by multiple search parameters by combining them with a comma:
http://localhost:8000/Patient
FHIR includes capabilities for performing a fulltext search across the textual contents of resources. Using the _content
parameter, the various textual fields in resources are matched.
For example, the following search query returns all Condition resources that contain the string "diabetes". Note that the search is not case-sensitive.
http://localhost:8000/Condition
FHIR also provides a second fulltext parameter, _text
, which can be used to search across resource Narratives.
FHIR provides a special query known as the $everything
operation, which returns all resources associated with a specific patient. In other words, it searches the patient's entire chart.
To invoke this operation on a specific patient, simply invoke the $everything
on a Patient resource instance. For example:
http://localhost:8000/Patient/1218d9e8-df8d-4f59-b21c-21f5fdff5a00/$everything
Note that in order to avoid overwhelming the client and server, the results of this operation are paged. You will find a link to the next page in the resulting Bundle. You can increase the page size by using the _count
parameter, for example:
http://localhost:8000/Patient/1218d9e8-df8d-4f59-b21c-21f5fdff5a00/$everything
Smile CDR provides an extra parameter on the $everything
operation called _content
, which performs a fulltext search across the entire patient chart. For example, to search for any resources in the patient's chart containing the term "coronary", invoke the following:
http://localhost:8000/Patient/1218d9e8-df8d-4f59-b21c-21f5fdff5a00/$everything
For more information regarding the $everything
command.