FHIR search examples

Important

Azure Healthcare APIs is currently in PREVIEW. The Supplemental Terms of Use for Microsoft Azure Previews include additional legal terms that apply to Azure features that are in beta, preview, or otherwise not yet released into general availability.

Below are some examples of using FHIR search operations, including search parameters and modifiers, chain and reverse chain search, composite search, viewing the next entry set for search results, and searching with a POST request. For more information about search, see Overview of FHIR Search.

Search result parameters

_include

_include searches for resources that include the specified parameter of the resource. For example, you can search across MedicationRequest resources to find only the ones that include information about the prescriptions for a specific patient, which is the reference parameter patient. In the example below, this will pull all the MedicationRequests and all patients that are referenced from the MedicationRequests:

 GET [your-fhir-server]/MedicationRequest?_include=MedicationRequest:patient

Note

_include and _revinclude are limited to 100 items.

_revinclude

_revinclude allows you to search the opposite direction as _include. For example, you can search for patients and then reverse include all encounters that reference the patients:

GET [your-fhir-server]/Patient?_revinclude=Encounter:subject

_elements

_elements narrows down the search result to a subset of fields to reduce the response size by omitting unnecessary data. The parameter accepts a comma-separated list of base elements:

GET [your-fhir-server]/Patient?_elements=identifier,active

In this request, you'll get back a bundle of patients, but each resource will only include the identifier(s) and the patient's active status. Resources in this returned response will contain a meta.tag value of SUBSETTED to indicate that they're an incomplete set of results.

Search modifiers

:not

:not allows you to find resources where an attribute is not true. For example, you could search for patients where the gender is not female:

GET [your-fhir-server]/Patient?gender:not=female

As a return value, you would get all patient entries where the gender is not female, including empty values (entries specified without gender). This is different than searching for Patients where gender is male, since that would not include the entries without a specific gender.

:missing

:missing returns all resources that don't have a value for the specified element when the value is true, and returns all the resources that contain the specified element when the value is false. For simple data type elements, :missing=true will match on all resources where the element is present with extensions but has an empty value. For example, if you want to find all Patient resources that are missing information on birth date, you can do:

GET [your-fhir-server]/Patient?birthdate:missing=true

:exact

:exact is used for string parameters, and returns results that match the parameter precisely, such as in casing and character concatenating.

GET [your-fhir-server]/Patient?name:exact=Jon

This request returns Patient resources that have the name exactly the same as Jon. If the resource had patients with names such as Jonathan or joN, the search would ignore and skip the resource as it does not exactly match the specified value.

:contains

:contains is used for string parameters and searches for resources with partial matches of the specified value anywhere in the string within the field being searched. contains is case insensitive and allows character concatenating. For example:

GET [your-fhir-server]/Patient?address:contains=Meadow

This request would return you all Patient resources with address fields that have values that contain the string "Meadow". This means you could have addresses that include values such as "Meadowers" or "59 Meadow ST" returned as search results.

To perform a series of search operations that cover multiple reference parameters, you can "chain" the series of reference parameters by appending them to the server request one by one using a period .. For example, if you want to view all DiagnosticReport resources with a subject reference to a Patient resource that includes a particular name:

 GET [your-fhir-server]/DiagnosticReport?subject:Patient.name=Sarah

This request would return all the DiagnosticReport resources with a patient subject named "Sarah". The period . after the field Patient performs the chained search on the reference parameter of the subject parameter.

Another common use of a regular search (not a chained search) is finding all encounters for a specific patient. Patients will often have one or more Encounters with a subject. To search for all Encounter resources for a Patient with the provided id:

GET [your-fhir-server]/Encounter?subject=Patient/78a14cbe-8968-49fd-a231-d43e6619399f

Using chained search, you can find all the Encounter resources that matches a particular piece of Patient information, such as the birthdate:

GET [your-fhir-server]/Encounter?subject:Patient.birthdate=1987-02-20

This would allow not just searching Encounter resources for a single patient, but across all patients that have the specified birth date value.

In addition, chained search can be done more than once in one request by using the symbol &, which allows you to search for multiple conditions in one request. In such cases, chained search "independently" searches for each parameter, instead of searching for conditions that only satisfy all the conditions at once:

GET [your-fhir-server]/Patient?general-practitioner:Practitioner.name=Sarah&general-practitioner:Practitioner.address-state=WA

This would return all Patient resources that have "Sarah" as the generalPractitioner and have a generalPractitioner that has the address with the state WA. In other words, if a patient had Sarah from the state NY and Bill from the state WA both referenced as the patient's generalPractitioner, the would be returned.

For scenarios in which the search has to be an AND operation that covers all conditions as a group, refer to the composite search example below.

Chain search lets you search for resources based on the properties of resources they refer to. Using reverse chain search, allows you do it the other way around. You can search for resources based on the properties of resources that refer to them, using _has parameter. For example, Observation resource has a search parameter patient referring to a Patient resource. To find all Patient resources that are referenced by Observation with a specific code:

GET [base]/Patient?_has:Observation:patient:code=527

This request returns Patient resources that are referred by Observation with the code 527.

In addition, reverse chain search can have a recursive structure. For example, if you want to search for all patients that have Observation where the observation has an audit event from a specific user janedoe, you could do:

GET [base]/Patient?_has:Observation:patient:_has:AuditEvent:entity:agent:Practitioner.name=janedoe

To search for resources that meet multiple conditions at once, use composite search that joins a sequence of single parameter values with a symbol $. The returned result would be the intersection of the resources that match all of the conditions specified by the joined search parameters. Such search parameters are called composite search parameters, and they define a new parameter that combines the multiple parameters in a nested structure. For example, if you want to find all DiagnosticReport resources that contain Observation with a potassium value less than or equal to 9.2:

GET [your-fhir-server]/DiagnosticReport?result.code-value-quantity=2823-3$lt9.2

This request specifies the component containing a code of 2823-3, which in this case would be potassium. Following the $ symbol, it specifies the range of the value for the component using lt for "less than or equal to" and 9.2 for the potassium value range.

Composite search parameters can also be used to filter multiple component code value quantities with an OR. For example, to express the query to find diastolic blood pressure greater than 90 OR systolic blood pressure greater than 140:

GET [your-fhir-server]/Observation?component-code-value-quantity=http://loinc.org|8462-4$gt90,http://loinc.org|8480-6$gt140

Search the next entry set

The maximum number of entries that can be returned per a single search query is 1000. However, you might have more than 1000 entries that match the search query, and you might want to see the next set of entries after the first 1000 entries that were returned. In such case, you would use the continuation token url value in searchset as in the Bundle result below:

    "resourceType": "Bundle",
    "id": "98731cb7-3a39-46f3-8a72-afe945741bd9",
    "meta": {
        "lastUpdated": "2021-04-22T09:58:16.7823171+00:00"
    },
    "type": "searchset",
    "link": [
        {
            "relation": "next",
            "url": "[your-fhir-server]/Patient?_sort=_lastUpdated&ct=WzUxMDAxNzc1NzgzODc5MjAwODBd"
        },
        {
            "relation": "self",
            "url": "[your-fhir-server]/Patient?_sort=_lastUpdated"
        }
    ],

And you would do a GET request for the provided URL under the field relation: next:

GET [your-fhir-server]/Patient?_sort=_lastUpdated&ct=WzUxMDAxNzc1NzgzODc5MjAwODBd

This will return the next set of entries for your search result. The searchset is the complete set of search result entries, and the continuation token url is the link provided by the server for you to retrieve the entries that don't show up on the first set because the restriction on the maximum number of entries returned for a search query.

Search using POST

All of the search examples mentioned above have used GET requests. You can also do search operations using POST requests using _search:

POST [your-fhir-server]/Patient/_search?_id=45

This request would return all Patient resources with the id value of 45. Just as in GET requests, the server determines which of the set of resources meets the condition(s), and returns a bundle resource in the HTTP response.

Another example of searching using POST where the query parameters are submitted as a form body is:

POST [your-fhir-server]/Patient/_search
content-type: application/x-www-form-urlencoded

name=John

Next steps