FHIR (Fast Healthcare Interoperability Resources) is a standard for exchanging healthcare information electronically. It's a RESTful API that allows developers to access and share patient data in a standardized way.
Searching for FHIR resources is the primary way to query and get insights from FHIR data. Constructing FHIR queries for specific datatypes can be tedious, requiring you to work with multiple information sources.
Hence, in this blog post, let’s break down everything you need to know about writing queries for Healthcare API FHIR stores. It will cover the basics of FHIR queries, including different types, syntax, and how to use parameters to filter and sort your results and provide lots of examples to make it super easy to understand.
By the end of this blog post, you will be able to write FHIR queries with confidence. So let's get started!
You can search for FHIR resources in the Cloud Healthcare API in the following ways:
In this blog, we’ll be talking about how to search using REST-APIs. To search for FHIR resources with the REST API, you can call the method using GET or POST requests.
Please check the official documentation for the basic “string” search example.
Let’s look at querying all datatypes. I’ve also attached FHIR documentation links for individual data types which you should look at.
Utilize the "&" operator to combine any of the two queries provided below into a single expression.
Utilize the "," operator to combine any of the two queries provided below into a single expression.
Use Modifiers and Prefixes in below queries based on your use case.
Querying with data types |
|||
FHIR Field |
Datatype |
Sample Query [BASE_URL= |
Query Description |
Name |
Reference + HumanName (string) |
${BASE_URL}/Encounter?subject:Patient.name=Clara |
This Query finds all the encounter resources that matches “Clara” in any of the string fields in the Encounter.subject.name |
Last Name |
HumanName.family (string) |
${BASE_URL}/Patient/?family%3Aexact=TestLastName |
This Query finds all the patient resources where Patient.name.family is TESTLastName |
Encounter period search |
Period (date) |
${BASE_URL}/Encounter?date=gt2023-02-02T00:00:00.000Z |
This Query finds all the encounter resources where Encounter.period date is greater than 2023-02-02T00:00:00.000Z |
Observation valueQuantity |
${BASE_URL}/Observation?value-quantity=3.2|http://example.com|mg |
This Query finds all the Observation resources where Observation.valueQuntity.value = 3.2 , Observation.valueQuantity.system = “http://example.com” and Observation.valueQuantity.code = “mg” |
|
Diagnosis Description |
CodeableConcept (token) |
${BASE_URL}/Encounter?reason-code:text=COVID-19 |
This Query finds all the encounter resources where Encounter.reasonCode.text matches “COVID-19” |
Visit Type |
CodeableConcept (token) |
${BASE_URL}/Encounter?type=http://example.com/|126 |
This Query finds all the encounter resources where Encounter.type.code = 126 and Encounter.type.system = http://example.com |
Diag Code |
CodeableConcept (token) |
${BASE_URL}/Encounter?reason-code=U0X1 |
This Query finds all the encounter resources where Encounter.reasonCode.code = U0X1 |
Patient Class |
Coding (token) |
${BASE_URL}/Encounter?class=AMB |
This Query finds all the encounter resources Encounter.class.code = AMB |
Observation code + Quantity |
CodeableConcept + Quantity (composite) |
${BASE_URL}/Observation?code-value-quantity=code$loinc|12907-2,value$ge150|http://unitsofmeasure.org|mmol/L |
This Query is a combination of token + Quantity, so it will return all the Observation resource with a LOINC code of "12907-2" and Observation Quantity value greater than “150 mmol/L” |
Admitted to? |
Reference + Name |
${BASE_URL}/Encounter?service-provider:Organization.name=TestOrg |
This Query finds all the encounter resources where Encounter.serviceProvider is TestOrg |
Member ID/MBI |
Reference + Identifier.value (string) (Chained Search) |
${BASE_URL}/Encounter?subject:Patient.identifier%3Aexact=Abcdefg |
This Query finds all the encounter resources where Encounter.subject.identifier = Abcdefg |
Discharge disposition |
Custom Search Parameter (token)[Example Below] |
${BASE_URL}/Encounter?hospitalization-dischargeDisposition:text=home |
This Query finds all the encounter resources where Encounter.hospitalization.dischargeDisposition.text = home |
Discharged To Location |
Custom Search Parameter (Reference)[Example Below] |
${BASE_URL}/Encounter?hospitalization-destination:Location.name=name |
This Query finds all the encounter resources where Encounter.location.location.name = name |
Certain search parameters, shown by a leading underscore like _id, apply to all resource types. These all-resource parameters are listed in the FHIR specification for the Resource type.
When using these search parameters, you can perform a search across multiple resource types by omitting the resource type from the request path. For example, using GET .../fhir?_id=1234 instead of GET .../fhir/Patient?_id=1234 searches across all FHIR resources instead of only a Patient resource.
Type |
Example |
Description |
_id (token) |
${BASE_URL}?_id=aA23 |
This Query returns all resources where Resource.id = aA23 |
_lastUpdate (date) |
${BASE_URL}?_lastUpdate=gt2010-10-01 |
This Query returns all resources where Resource.meta.lastUpdated is greater than 2010-10-01 |
_tag (token) |
${BASE_URL}?_tag=http://acme.org/codes|needs-review |
This Query returns all resources where Resource.meta.tag.system =http://acme.org/codes and Resource.meta.tag.code = needs-review |
_profile (uri) |
${BASE_URL}/DiagnosticReport?_profile=http://hl7.org/fhir/StructureDefinition/lipid |
This Query returns all DiagnosticReport resources where DiagnosticReport.meta.profile.uri = “http://hl7.org/fhir/StructureDefinition/lipid” |
_security (token) |
${BASE_URL}?_id=aA23 |
This Query returns all DiagnosticReport resources where DiagnosticReport.meta.profile.uri = “http://hl7.org/fhir/StructureDefinition/lipid” |
_content (string) |
${BASE_URL}?Condition?_content=(bone OR liver) and metastases |
This Query searches the entire content of the resource and this request returns all Condition resources with the word "metastases" and either "bone" or "liver" in the narrative. |
_text (string) |
${BASE_URL}?Condition?_text=(bone OR liver) and metastases |
The parameter _text performs the same type of match as above only on the Narrative fields |
_has (special) (Reverse chained search) |
${BASE_URL}/Patient?_has:Observation:patient:code=1234 |
This Query returns all the patient resources which are referenced by Observation resource with code 1234 |
_type (special) |
${BASE_URL}?_type=Observation,patient&patient=Patient/123 |
Returns all observation and patient resources for Patient id 123 |
Use the below queries to manage the results returned by the FHIR Store.
Type |
Example |
Description |
_sort (string) |
${BASE_URL}/Patient?_sort=birthdate |
Returns all the patients with birthdate sorted in ascending orderer, use “-birthdate” for descending order |
_count (number) |
${BASE_URL}/Patient?_sort=-birthdate&_count=5 |
Returns top 5 patients with birthdate descending order |
_include (string) |
${BASE_URL}/Observation?_include=Observation:subject |
This query along with observations includes all the patients resources referenced by observations |
_revinclude (string) |
${BASE_URL}/Patient?_revinclude=Observation:subject |
This query along with all the patient resources returns all the observations which refer the patient |
_elements(string) |
${BASE_URL}/Patient?_elements=identifier |
This query returns all patients with only identifier field |
The FHIR specification defines a set of standard search parameters, but not all FHIR fields are supported by these parameters. Custom search parameters can be used to enable searching on fields that are not supported by default. The composite and special types are not supported by HC-API currently.
Datatype |
Description |
Example |
Search parameter SHALL be a number (a whole number, or a decimal). |
||
Search parameter is on a date/time. The date format is the standard XML format, though other formats may be supported. |
||
Search parameter is a simple string, like a name part. Search is case-insensitive and accent-insensitive. May match just the start of a string. String parameters may contain spaces. |
||
Search parameter on a coded element or identifier. May be used to search through the text, display, code and code/codesystem (for codes) and label, system and key (for identifier). Its value is either a string or a pair of namespace and value, separated by a "|", depending on the modifier used. |
||
A reference to another resource (Reference or canonical). |
||
A search parameter that searches on a quantity. |
||
A search parameter that searches on a URI (RFC 3986). |
Example: For ADT(Admit Discharge Transfer information) we need “Encounter.hospitalization.dischargeDisposition” and “Encounter.hospitalization.destination” to be searchable, which are not part of custom search parameters.
Step 1: Find the datatype of the field from fhir documentation.For Encounter.hospitalization.dischargeDisposition the type is token and for Encounter.hospitalization.destination the type is reference.
Step 2: Create custom FHIR search for “Encounter.hospitalization.dischargeDisposition”
curl -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
--data "{
\"resourceType\": \"SearchParameter\",
\"url\": \"adtv1.0\",
\"base\": [\"Encounter\"],
\"code\": \"hospitalization-dischargeDisposition\",
\"name\": \"hospitalization-dischargeDisposition\",
\"type\": \"token\",
\"expression\": \"Encounter.hospitalization.dischargeDisposition\",
\"status\": \"active\",
\"description\": \"search on statement regarding the discharge disposition\"
}" \
"https://healthcare.googleapis.com/v1beta1/projects/<Name>/locations/<location>/datasets/healthcare-dataset/fhirStores/final-fhir-store/fhir/SearchParameter"
Step 3: Create another custom FHIR search for “Encounter.hospitalization.destination”
curl -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
--data "{
\"resourceType\": \"SearchParameter\",
\"url\": \"adtref1.0\",
\"base\": [\"Encounter\"],
\"code\": \"hospitalization-destination\",
\"name\": \"hospitalization-destination\",
\"type\": \"reference\",
\"target\": [\"Location\",\"Organization\"],
\"expression\": \"Encounter.hospitalization.destination\",
\"status\": \"active\",
\"description\": \"search on statement regarding the discharge location\"
}" \
"https://healthcare.googleapis.com/v1beta1/projects/<Name>/locations/<location>/datasets/healthcare-dataset/fhirStores/final-fhir-store/fhir/SearchParameter"
Step 4: Enable both the above search parameters
curl -X POST -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" -H "Content-Type: application/json; charset=utf-8" --data "{
\"canonicalUrls\": [\"adtv1.0\",\"adtref1.0\"],
}" "https://healthcare.googleapis.com/v1beta1/projects/<Name>/locations/<location>/datasets/healthcare-dataset/fhirStores/final-fhir-store:configureSearch"
Step 5: Please check the HC-API documentation to understand more customizations like extensions
Step 6: Once the search parameters are enabled you can Query the FHIR store, check the above Querying with Data Types section to get the sample Query for above custom search parameters