FHIR resources will typically refer to each other, forming a web of related and referenced resources.
Resources refer to each other using the Reference datatype, and can take several forms:
A simple example of a Patient resource with a reference to the Organization which manages the record is shown below:
{
"resourceType": "Patient",
"id": "example",
"name": [ {
"family": "Jones",
"given": [ "David" ]
} ],
"managingOrganization": {
"reference": "Organization/acme"
}
}
The corresponding Organization is shown below:
{
"resourceType": "Organization",
"id": "acme",
"name": "ACME Corporation"
}
Most references will only point in one direction. In other words, Patient contains a reference to its Organization, but Organization does not contain a reference to its patient.
The following example shows a collection of resources with various references. This data will be used for all of the examples on the rest of this page.
Selected search parameters are also shown for each resource, using the form: name (type): path
FHIR searches can be used to find resources which refer to other resources. For example, the following search finds any Observation resources which have patient P1 as a subject:
http://localhost:8000/Observation
Results: The search above will return the following resource: Observation/O1.
Searches may be performed using any search parameter with a parameter type of reference. For example, see the FHIR Patient Resource Default Search Parameters to see what is available out of the box. You can also create Custom Search Parameters.
FHIR also supports a search syntax called chaining, where you can find resources that refer to other resources, but using a property of the other resource that isn't the resource ID. This syntax takes the following form:
[resourceType]?[reference search parameter].[search parameter on reference target]=[value]
For example, suppose you wish to find all Observation resources belonging to a specific patient, but you have only the patient's identifier, not their ID. You can perform this search by searching for Observations using the subject search parameter, but then chaining on the Patient's identifier search parameter. This is shown in the example below:
http://localhost:8000/Observation
Results: The search above will return the following resource: Observation/O1
If you know the target type of the reference, it is possible to include it and improve the specificity of the search. You can do this by appending :[resourceType] before the dot. For example, the following search fetches Observations with a Patient subject named "smith".
This can be very helpful in terms of improving performance of this query, so you should always include the type of the target if you know it. This is the case because reference search parameters such as Observation?subject= can refer to multiple target types (in this case: Patient, Group, Device, Location, and several more) and the server will have to do more work if it needs to check for all of these possible target types.
http://localhost:8000/Observation
Results: The search above will return the following resource: Observation/O1.
In addition to searching for resources where a reference target has a given parameter value (i.e. chaining), you can also perform searches where a resource referring to the resource being searched for has a given target.
This is an advanced FHIR feature, and can be tricky to understand (and is generally tricky even for FHIR experts to remember the syntax!).
This syntax takes the form:
[resourceType]?_has:[referring resourceType]:[referring parameter]:[parameter]=[value]
An example may help to make this syntax more clear. Suppose you want to search for Patients named Simpson, but only include patients who are members of the group with identifier http://ids|8000
. The "named Simpson" part is easy: you can perform a normal search for Patient?name=Simpson. However, the group part is harder. The following example shows how to do this.
http://localhost:8000/Patient
Note the _has parameter. It includes the following segments:
Results: The search above will return the following resource: Patient/P1.
It is often convenient to be able to search for a collection of resources matching some given criteria, but to also include related resources in the same search result in order to avoid having to perform multiple lookups. This can be achieved using a search feature called includes.
Includes can be used to return any resources which are referred to by the resources returned by the initial search. This syntax takes the following forms:
[resourceType]?[any search parameters]&_include=* [resourceType]?[any search parameters]&_include=[resourceType]:[referring parameter]
The following example shows a search for any body-weight Observations, and includes the subject (Patient) associated with the returned Observations as well:
http://localhost:8000/Observation
Results: The search above will return the following resources: Observation/O1, Observation/O2, Patient/P1, and Patient/P2.
In addition to returning resources that are returned by search results, you can also instruct the _include parameter to return resources referred to by resources that were added to the search results by the _include parameter. This is done using a modifier called :iterate. (Note that in older versions of the FHIR specification, this modifier was called :recurse. Many servers will support both modifiers and treat them identically.)
The following example shows a search for any body-weight Observations, and includes the subject (Patient) associated with the returned Observations, as well as the Organizations referred to by the subject:
http://localhost:8000/Observation
Results: The search above will return the following resource: Observation/O1, Observation/O2, Patient/P1, Patient/P2, and Organization/O1. If the :iterate modifier had not been included on the second _include parameter, the Organization would not have been included in the results.
Resources can also be included based on references flowing in the other direction, meaning resources referring to the search results. This is referred to as reverse includes, or revincludes.
This syntax takes the following forms:
[resourceType]?[any search parameters]&_revinclude=* [resourceType]?[any search parameters]&_revinclude=[referring resourceType]:[referring parameter]
For example, the following search returns any patients with an identifier system of http://ids
, and also returns any Group or Encounter resources which refer to these patients. Note also the token syntax of "[system]|" which means tokens with the given system and any value:
http://localhost:8000/Patient
Results: The search above will return the following resources: Patient/P1, Patient/P2, Group/G1, Encounter/E1, and Encounter/E2.
While references between resources are almost always relative or absolute URLs to other separate resources, FHIR also provides a mechanism called containing where you can embed a resource inside another resource.
This feature is intended for situations where you do not have enough information to create a discrete identity for the resource in question. For example, suppose you have a collection of Observations you wish to model in FHIR, and you have the name and birthdate for the subject but no other information about them. In this case, you have no way of knowing whether two observations belonging to "John Smith" refer to the same person or not. This is an appropriate time to use contained resources.
Contained resources are placed within an array element called "contained" at the root of the resource, and are referred to elsewhere using the syntax { "reference": "#[id]" }
. The following example shows an Observation with a contained Patient.
{ "resourceType": "Observation", "id": "O1", "contained": [ | |
Contained Patient resource within Observation resource | { "resourceType": "Patient", "id": "pat", "name": [ { "family": "Smith", "given": [ "John" ] } ], "birthDate": "1980-07-22" } |
], "subject": { | |
Fragment reference to contained resource | "reference": "#pat" |
}, "status": "final", "code": { "coding": [ { "system": "http://loinc.org", "code": "29463-7", "display": "Body Weight" } ] }, "valueQuantity": { "value": 67.1, "unit": "kg", "system": "http://unitsofmeasure.org", "code": "kg" } } |
Chaining can be used to search values in contained resources. The following URL can be used to fetch the resource above:
http://localhost:8000/Observation
This example combines chaining and reverse chaining to create a very complicated query that achieves a very interesting result.
Suppose you want to search for Body-Weight observations, but only return observations where the subject is in a collection of patients.
If your collection of patients is small, a simple OR expression on a subject search parameter can do the trick as shown below:
http://localhost:8000/Observation
Results: The search above will return the following resource: Observation/O1, Observation/O2.
However, what if your collection of patients is too large to be maintainable in a URL? Or what if you want to dynamically manage this collection of patients and reuse it across queries? In that case, you could create a Group resource and manage your list of patients there.
Then, you can perform the desired search using the Observation subject search parameter, but chaining on the patient using a reverse chain towards the Group resource. The following example shows this:
http://localhost:8000/Observation
Note the subject parameter. It includes the following segments:
Results: The search above will return the following resources: Observation/O1, and Observation/O2.