FHIR Resource Search Methodologies
You can search FHIR resources using Particle's FHIR API. In general, Particle's API follows the FHIR spec for how searches are performed. However, since there are some distinctions, this guide will show you when and how to use different FHIR search parameters. We've also included examples of the types of searches that our clients use frequently in practice.
If you have any questions about your specific use case and how to search on Particle, reach out to your Particle account team.
Searching by date
Date searches are one of the most common types of searches our customers perform over resources. When working with dates, the following questions are common:
- How does FHIR handle date searches?
- Which Particle resources support date searching?
- Which parameters are supported? (
date,effective, orperiod?) - How do these parameters map to the underlying FHIR?
- Which parameters are supported? (
We'll answer these questions with examples below.
How does FHIR handle date searches?
FHIR handles date searching by allowing you to search over dates that are equal to (eq), less than (lt), greater than (gt), greater than or equals to (ge), or less than or equals to a given date (le). FHIR supports all of these search parameters in the form of ={comparator_prefix}YYYY-MM-DD. Specifics on all comparator prefixes can be found here.
- Date searches are addressed in this section of the FHIR spec.
For some kinds of resources that support date searching (e.g. the
effectivedate in aMedicationStatement), there may be instances of that resource where there is no available date. In that case, these instances will be excluded from date search results for that resource. This is in line with how the FHIR spec defines how to handle date searches.To isolate these resources without available dates, use the
:missingsearch modifier. When searching medication statements, for example, chaineffective:missing=trueto your query.
Date searches using the Particle FHIR API
Below are the Particle resources that support date parameter searches, along with which parameter to use and what each parameter maps to in the underlying FHIR.
| Resource name | Search parameter(s) supported | Parameter(s) map to... |
|---|---|---|
| AllergyIntolerance | onset and date | Onset period (AllergyIntolerance.reaction.onset) and Recorded date (AllergyIntolerance.recordedDate) |
| CarePlan | activity-date | Activity date (CarePlan.activity.detail.scheduled) |
| Composition | date and period | Composition editing time (Composition.date) and Clinical event date (Composition.event.period) |
| Condition | onset-date | Date condition began (onsetDateTime) |
| DiagnosticReport | date | Effective period (DiagnosticReport.effective) |
| Encounter | date | Encounter period (Encounter.period) |
| Immunization | date | Administration date (Immunization.occurrence) |
| MedicationStatement | effective | Date period when the medication was/is/will be taken (MedicationStatement.effective) |
| Observation | date | Obtained date (Observation.effective) |
| Procedure | date | When procedure was performed (Procedure.performed) |
Example date searches
To show how date searches work with parameters and comparators, let's consider an Encounter where the Encounter.period is the following:
"period": {
"end": "2021-10-24T00:00:00+00:00",
"start": "2021-10-19T00:00:00+00:00"
}date=ge2021-10-22&date=lt2021-10-24- This date search would return the example Encounter above
date=lt2021-10-19- This date search would not return the example Encounter above
Resource date fields may include a start and end date value; in this case, the date parameter must be TRUE for at least one for either the start or end date. See examples below:
"period": {
"end": "2021-09-14T14:18:06+00:00",
"start": "2021-09-08T00:00:00+00:00"
}date=ge2021-09-08&date=lt2021-09-15- This date search would return the example Encounter above
date=ge2021-09-08&date=lt2021-09-14returns the same Encounterdate=ge2021-09-09&date=lt2021-09-14also returns the same Encounter
Finally, here is an Encounter where no end date was provided:
"period": {
"start": "2021-09-27T00:00:00+00:00"
}date=ge2021-09-09&date=lt2021-09-28- This date search would return the Encounter above
date=ge2021-09-09&date=lt2021-09-27- This date search would not return the Encounter above
Paginating searches and limiting results returned
🔥 See HL7 FHIR Spec
The _count search parameter limits the total number of resources that are returned on a single page. If, for example, a patient has 500 observation resources available, and a client only wants to return 50 observations per page, _count=50 can be added to the search request to apply this to the response:
https://api.particlehealth.com/R4/MedicationStatement/?patient={patient_id}&_count=50
The last element at the bottom of the response will contain a JSON element labeled link. If one of the relation elements in link contains next, this indicates there are more pages as a part of the response. If "relation": "next" is present, copy the url and use it as the next endpoint to query. That will provide the next page of entries. Once there is no "relation": "next" present, there are no more entries or pages to review.
Example:
"link": [
{
"relation": "search",
"url": "search_url"
},
**{
"relation": "next",
"url": "url_to_return_next_50_resources"
}**,
{
"relation": "first",
"url": "url_to_first_page"
},
{
"relation": "self",
"url": "url_to_current_page"
}
]🔥 The maximum number of resources that the API will return per page is 1000. To force the maximum number of resources returned on each query and avoid needing to page through responses (for resource counts under 1000), add
_count=1000to your search.If over 1000 resources exist, the link array must be used to paginate through all results.
Sorting search results
🔥 See HL7 FHIR spec
The _sort search parameter sorts the bundle of resource requests by three main terms:
- date: If the resources support date searching, you can return a chronological list of resources by using
_sortwith the appropriate date search parameter.- For example, sorting by the effective period for a
MedicationStatementresource would take the_sort=effectivesearch term, while sorting on anObservationdate (Observation.effective) would require the_sort=dateparameter. - Use a minus (
-) symbol to return descending results. For example,_sort=datereturns the resources in ascending order (from the earliest historical date, going forward), while_sort=-datereturns the resources in descending order (from today, going backward in time).
- For example, sorting by the effective period for a
- status: Using
_sort=statuswill return results ordered by status. Information about statuses can be found in the FHIR spec for each resource. Some examples are:- MedicationStatement/Medication/MedicationRequest statuses are
active|completed|entered-in-error|intended|stopped|on-hold|unknown|not-taken - CarePlan statuses are
draft|active|on-hold|revoked|completed|entered-in-error|unknown - DiagnosticReport statuses are
registered|partial|preliminary|final
- MedicationStatement/Medication/MedicationRequest statuses are
- category: Using
_sort=categorywill return results ordered by category, if the resource has a category. Information about categories can be found in the FHIR spec for each resource. Some examples are:- AllergyIntolerance categories are
food|medication|environment|biologic - Condition categories are
problem-list-item|encounter-diagnosis
- AllergyIntolerance categories are
Searching by code
Codes are used frequently in medicine, for diagnoses, medications, procedures, and more, so it can be quite useful to search over them. FHIR resources can contain one or more codes from different code systems. For example:
Medicationresources often contain RxNorm and PHIN codesCondition&Observationresources often contain SNOMED and LOINC codes
Searching for specific code within a resource is typically as simple as adding the following parameter to a search:
code={code_of_interest}
For example, if a client is interested in Observation resources that contain lab results for A1c values, they could search for the LOINC code specific to A1c (4548-4) using the following request:
https://api.particlehealth.com/R4/Observation?patient={patient_id}&code=4548-4
That request would search for all Observations that contain a code array that looks like this:
"code": {
"coding": [
{
"code": "4548-4",
"system": "urn:oid:2.16.840.1.113883.6.1"
}
],
"text": "Hemoglobin A1C"
}Within a particular code object, there's a "system" ID, which represents the Object Identifier (OID) for a system. In this case, 2.16.840.1.113883.6.1 is the OID for the LOINC code system. Each code system has a unique OID, but below are some of the most common that we see.
| OID | System Name |
|---|---|
| 2.16.840.1.113883.6.1 | LOINC |
| 2.16.840.1.113883.6.69 | PHIN VADS |
| 2.16.840.1.113883.6.88 | RxNorm |
| 2.16.840.1.113883.6.90 | ICD-10 |
| 2.16.840.1.113883.6.96 | SNOMED |
| 2.16.840.1.113883.6.103 | ICD-9 |
| 2.16.840.1.113883.6.208 | National Drug Data File (NDDF) |
To return all codes for a specific code system (e.g. all providers that returned an associated NPI number), use the {search_term}={system}|{code} search methodology (in this case, omitting the code).
Here are a few examples:
code=urn:oid:2.16.840.1.113883.6.88| (all resources with a LOINC code present)
identifier=urn:oid:2.16.840.1.113883.4.1| (all Patient resources with a SSN available)
As mentioned above, most resources that contain some sort of code will support the code search parameter; search terms supported by each resource can be found at the bottom of each resource's FHIR page.
Other useful code system resources can be found below:
There are scenarios where a non-standard or unknown code is provided by the source EMR. In scenarios where you’re looking for a specific value (e.g. A1c's), string searches may be required to fill in any gaps from your primary code searches.
Below are a few examples of how you may search for an A1c value using the FHIR
_contentsearch parameter:
code=UNK&_content=hemoglobin&_content=a1c
code=unknown&_content=hemoglobin&_content=a1c
Searching by resource content and description
🔥 See HL7 FHIR spec
The _content search parameter enables customers to search the content of the resource in its entirety. The _text search parameter enables customers to search the text contained within the resource's narrative.
A resource's narrative is intended to be a human-readable summary of the resource. It will be represented as follows and will contain data — often as freeform text with some HTML styling guidance — that will provide additional context about the resource itself:
"text": {
"div": "some narrative text",
"status": "generated"
},_text example
_text exampleThe following search query could be used to find MedicationStatements that mention "nebulization" for asthma treatment:
https://api.particlehealth.com/R4/MedicationStatement/?patient={patient_id}&_text=nebulization
The result may be a list of MedicationStatement resources that contain a narrative that looks something like this:
"text": {
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">Take 2.5 mg by nebulization 3 (three) times daily.</div>",
"status": "generated"
}_content example
_content exampleUse the _content search parameter to search the entire contents of a particular resource. For example, the following query could be used to find the Composition resource that a MedicationStatement with ID 749f091e-6f15-4741-9e4a-c035f73b2247 came from:
https://api.particlehealth.com/R4/Composition/?patient={patient_id}&_content=749f091e-6f15-4741-9e4a-c035f73b2247
This search query would only return the Composition that contains this MedicationStatement, and nothing else.
Including referenced resources in search results
🔥 See HL7 FHIR spec
Using the _include and _revinclude search parameters, the search results can include other resources that have a reference link to the main result queried. Referencing is common in FHIR: for example, a MedicationStatement can reference Medication resources, or a DiagnosticReport can reference Observation resources.
Using the _include search parameter, the desired child reference will be appended to the response for a GET /:resource (SEARCH) request. This limits the number of consecutive queries that need to be performed. For example, getting the details for all Medication resources within a MedicationStatement can done in one query instead of several by including the Medication resource in a query for the MedicationStatement.
The _revinclude search parameter accomplishes the reverse: it includes the parent reference in the search request. For example, given a Medication resource, _revinclude can be used to find the original MedicationStatement that references the Medication.
From the FHIR spec:
Parameter values for both
_includeand_revincludehave three parts, separated by a:character:
- The name of the source resource from which the join comes
- The name of the search parameter which must be of type reference
- (Optional) A specific type of target resource (for when the search parameter refers to multiple possible target types)
🔥 The
_includeparameter also supports wildcard (*) searches. This enables clients to return all resources referenced within the target resource.
https://api.particlehealth.com/R4/Encounter/?patient=](https://api.particlehealth.com/R4/Encounter/?patient=)patient_id&_include=*, for example, will return all referencedCondition,Location, andPractitionerRoleresources contained within.
_include example
_include exampleTo include details about every Medication resource referenced within a MedicationStatement resource, the following search query could be used:
A sample response is given below. Note that the MedicationStatement resource's search mode is specified as include.
{
"resourceType": "Bundle",
"type": "searchset",
"total": 1,
"entry": [
{
"fullUrl": "https://api.particlehealth.com/R4/MedicationStatement/42a6dd0d-e640-464f-b46c-e8d0a44242fb",
"resource": {
"dosage": [
{
"doseAndRate": [
{
"doseQuantity": {
"unit": "mg",
"value": 150
}
}
],
"patientInstruction": "Take 150 mg by mouth daily.",
"route": {
"coding": [
{
"code": "C38288",
"display": "Oral",
"system": "urn:oid:2.16.840.1.113883.3.26.1.1"
}
],
"text": "Oral"
}
}
],
"id": "a6bf3f31-fd59-4d4a-a4b5-4e9fdb89cee9",
"identifier": [
{
"system": "urn:uuid:BBDEFBCA-40CF-11EC-921E-005056BC7C78",
"value": "UNK"
}
],
"informationSource": {
"reference": "PractitionerRole/20800"
},
"medicationReference": {
"reference": "Medication/d44de379-8b7e-4874-827e-7240c4095575"
},
"meta": {
"lastUpdated": "2021-11-08T20:12:07.322669+00:00",
"versionId": "MTYzNjQwMjMyNzMyMjY2OTAwMA"
},
"resourceType": "MedicationStatement",
"status": "active",
"subject": {
"reference": "Patient/3a8ca478-d6f0-4f2a-96cf-9a704e32502e"
},
"text": {
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">Take 150 mg by mouth daily.</div>",
"status": "generated"
}
},
"search": {
"mode": "match"
}
},
{
"fullUrl": "https://api.particlehealth.com/R4/Medication/d44de379-8b7e-4874-827e-7240c4095575",
"resource": {
"code": {
"coding": [
{
"code": "197319",
"system": "urn:oid:2.16.840.1.113883.6.88"
},
{
"code": "0378-0137-01",
"system": "urn:oid:2.16.840.1.113883.6.69"
},
{
"code": "203487",
"system": "urn:oid:2.16.840.1.113883.6.208"
}
],
"text": "allopurinol (ZYLOPRIM) 100 mg tablet"
},
"id": "0baa7721-ad24-4f6d-817d-6d1d631ac570",
"meta": {
"lastUpdated": "2021-11-08T20:12:07.322669+00:00",
"versionId": "MTYzNjQwMjMyNzMyMjY2OTAwMA"
},
"resourceType": "Medication"
},
"search": {
"mode": "include"
}
}
]
}_revinclude example
_revinclude exampleTo search for Medications of a certain code and the parent MedicationStatement resources associated with them, the following query could be used:
A sample response is given below. Note that the Medication resource's search mode is specified as _revinclude.
{
"resourceType": "Bundle",
"type": "searchset",
"total": 1,
"entry": [
{
"fullUrl": "https://api.particlehealth.com/R4/Medication/74d3504c-0ac3-429e-981e-69608f70fafe",
"resource": {
"code": {
"coding": [
{
"code": "391937",
"system": "urn:oid:2.16.840.1.113883.6.88"
},
{
"code": "50383-779-31",
"system": "urn:oid:2.16.840.1.113883.6.69"
},
{
"code": "568862",
"system": "urn:oid:2.16.840.1.113883.6.208"
}
],
"text": "lactulose (CHRONULAC) 20 gram/30 mL Soln solution"
},
"id": "74d3504c-0ac3-429e-981e-69608f70fafe",
"meta": {
"lastUpdated": "2021-11-08T20:12:05.590781+00:00",
"versionId": "MTYzNjQwMjMyNTU5MDc4MTAwMA"
},
"resourceType": "Medication"
},
"search": {
"mode": "match"
}
},
{
"fullUrl": "https://api.particlehealth.com/R4/MedicationStatement/f2fd9c0d-4f1e-46f5-b9e5-f1f4b7c5199a",
"resource": {
"dosage": [
{
"doseAndRate": [
{
"doseQuantity": {
"unit": "g",
"value": 10
}
}
],
"patientInstruction": "Take 10 g by mouth as needed.",
"route": {
"coding": [
{
"code": "C38288",
"display": "Oral",
"system": "urn:oid:2.16.840.1.113883.3.26.1.1"
}
],
"text": "Oral"
}
}
],
"id": "f2fd9c0d-4f1e-46f5-b9e5-f1f4b7c5199a",
"identifier": [
{
"system": "urn:uuid:ADBBCC76-40CF-11EC-8E28-005056BC7C78",
"value": "UNK"
}
],
"informationSource": {
"reference": "PractitionerRole/20800"
},
"medicationReference": {
"reference": "Medication/74d3504c-0ac3-429e-981e-69608f70fafe"
},
"meta": {
"lastUpdated": "2021-11-08T20:12:05.590781+00:00",
"versionId": "MTYzNjQwMjMyNTU5MDc4MTAwMA"
},
"resourceType": "MedicationStatement",
"status": "active",
"subject": {
"reference": "Patient/6c9c5478-9313-45f5-aaa0-bdf6c39dc287"
},
"text": {
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">Take 10 g by mouth as needed.</div>",
"status": "generated"
}
},
"search": {
"mode": "include"
}
}
]
}And / Or Searches
FHIR also enables implementers to perform and/or searching when trying to find specific values.
OR searches can be performed by separating the parameters by a comma:
code=17856-6,4548-4says find any resource with code17856-6OR4548-4
AND searches can be separated by an &
code=4548-4&_content=a1cfinds all resources that have both a code equal to4548-4ANDa1csomewhere in the body of the resource of interest
Updated 3 months ago
