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
effective
date 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
:missing
search modifier. When searching medication statements, for example, chaineffective:missing=true
to 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.occurence ) |
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-14
returns the same Encounterdate=ge2021-09-09&date=lt2021-09-14
also 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=1000
to 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
_sort
with the appropriate date search parameter.- For example, sorting by the effective period for a
MedicationStatement
resource would take the_sort=effective
search term, while sorting on anObservation
date (Observation.effective) would require the_sort=date
parameter. - Use a minus (
-
) symbol to return descending results. For example,_sort=date
returns the resources in ascending order (from the earliest historical date, going forward), while_sort=-date
returns the resources in descending order (from today, going backward in time).
- For example, sorting by the effective period for a
- status: Using
_sort=status
will 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=category
will 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:
Medication
resources often contain RxNorm and PHIN codesCondition
&Observation
resources 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
_content
search 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
_include
and_revinclude
have 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
_include
parameter 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
, andPractitionerRole
resources 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-4
says find any resource with code17856-6
OR4548-4
AND searches can be separated by an &
code=4548-4&_content=a1c
finds all resources that have both a code equal to4548-4
ANDa1c
somewhere in the body of the resource of interest
Updated 10 months ago