Chaining Searches
Chaining search parameters allows you to filter your searches based on the parameters of another resource which is related to the target resource through one or more references. This can reduce what might otherwise be a series of searches into just a single action.
Chained searches are similar to using _include
or _revinclude
parameters, but it will not return the referenced resources, only filter based on their parameters. The primary benefit of this is it allows for easy pagination since you know you will only receive results of one resource type. See the paginated search docs for more details.
Chained search is only available when using the FHIR Rest API as described here. If you are using GraphQL, chained search functionality is not supported.
Forward Chained Search
Search parameters with the reference
type can be chained together to search on the elements of the referenced resource.
In the below example we search for all Observation
resources that are linked to a Patient
with the name of 'homer' using the syntax patient.name=homer
. The way to read this is "search for all Observation
resources that reference a Patient
(using the patient
search parameter) and has a name of 'homer'.
Example: Search for any Observations
about a Patient
with the name 'homer'
- Typescript
- CLI
- cURL
await medplum.searchResources('Observation', {
'patient.name': 'homer',
});
medplum get 'Observation?patient.name=homer'
curl 'https://api.medplum.com/fhir/R4/Observation?patient.name=homer' \
-H 'authorization: Bearer $ACCESS_TOKEN' \
-H 'content-type: application/fhir+json' \
The target resource for every link in the chain must be unambiguous. If a search parameter can reference multiple resource types, you must specify the resource type in your search.
Just like the example above, the below example searches for all Observation
resources linked to a Patient
with a name of 'homer', this time using the syntax subject:Patient.name=homer
. The way to read this is "search for all Observation
resources whose subject
parameter is of type Patient
and has a name 'homer'".
In the above example, the patient
parameter can only search for Patient
resources, so it was not necessary to explicitly state which resource type we were searching for.
The general syntax for a forward chained search is <reference searchParam>:<referenced resource type>.<referenced resource searchParam>=<value>
.
Example: Search for any Observations
about a subject that is a Patient
with the name 'homer'
- Typescript
- CLI
- cURL
await medplum.searchResources('Observation', {
'subject:Patient.name': 'homer',
});
medplum get 'Observation?subject:Patient.name=homer'
curl 'https://api.medplum.com/fhir/R4/Observation?subject:Patient.name=homer' \
-H 'authorization: Bearer $ACCESS_TOKEN' \
-H 'content-type: application/fhir+json' \
You can include more than one link in your chained search. In the below example, we search for Observation
resources that are linked to an Encounter
done by a service-provider with the name of 'Kaiser'.
Example: A chained search that chains multiple parameters
- Typescript
- CLI
- cURL
await medplum.searchResources('Observation', {
'encounter:Encounter.service-provider.name': 'Kaiser',
});
medplum get 'Observation?encounter:Encounter.service-provider.name=Kaiser'
curl 'https://api.medplum.com/fhir/R4/Observation?encounter:Encounter.service-provider.name=Kaiser' \
-H 'authorization: Bearer $ACCESS_TOKEN' \
-H 'content-type: application/fhir+json' \
The _filter
search parameter is not currently supported when using chained search. This is on the Medplum road map, but there is no firm date when it is expected to be implemented. You can follow this issue for updates.
Reverse Chained Search
Chained references can also be constructed in reverse, filtering on other resources that reference your target search resource. This is done using the _has
parameter, which has a special syntax: _has:<next resource type>:<link parameter>:<next parameter>
.
For example, Patient?_has:Observation:subject:status=preliminary
would select Patient
resources that have an Observation
pointing to them as the subject
and are also in preliminary status.
For reverse chaining, the referenced type of the link parameter is never ambiguous: the previous resource type in the chain is used.
As another example, you may want to search for any Patient
resources with a heart rate above 150 (Loinc Code 8867-4) Observation
made about them.
Example: Search for any Patients
that have had an observed heart rate above 150
- Typescript
- CLI
- cURL
await medplum.searchResources('Patient', {
_has: 'Observation:subject:code=8867-4',
});
medplum get 'Patient?_has:Observation:subject:code=8867-4'
curl 'https://api.medplum.com/fhir/R4/Patient?_has:Observation:subject:code=8867-4' \
-H 'authorization: Bearer $ACCESS_TOKEN' \
-H 'content-type: application/fhir+json' \
In the above example _has:Observation
filters for Patient
resources that have an Observation
. The :subject
filters for Observation
resources that reference a Patient
in the subject field. This is based on our initial search for a Patient
. Finally, :code=11557-6
filters for that specific code on the Observation
.
Nesting reverse chained searches
It is also possible to nest the _has
parameter.
In this example we search for a Specimen
that is referenced by a DiagnosticReport
that originated from a Procedure
on the date of 2023-11-12
.
Example: Nested reversed chained search
- Typescript
- CLI
- cURL
await medplum.searchResources('Specimen', {
_has: 'DiagnosticReport:specimen:_has:Procedure:reason-reference:date=2023-11-12',
});
medplum get 'Specimen?_has:DiagnosticReport:specimen:_has:Procedure:reason-reference:date=2023-11-12'
curl 'https://api.medplum.com/fhir/R4/Specimen?_has:DiagnosticReport:specimen:_has:Procedure:reason-reference:date=2023-11-12' \
-H 'authorization: Bearer $ACCESS_TOKEN' \
-H 'content-type: application/fhir+json' \
Combining forward and reverse chained search
You can mix and match chained parameters by combining a forward chained search with the _has
parameter.
In the below example, we search for a Patient
with an Observation
that was performed by a CareTeam
that has a member with the name of 'bob'.
Example: Combining reverse and forward chained search
- Typescript
- CLI
- cURL
await medplum.searchResources('Patient', {
_has: 'Observation:subject:performer:CareTeam.participant:Practitioner.name=bob',
});
medplum get 'Patient?_has:Observation:subject:performer:CareTeam.participant:Practitioner.name=bob'
curl 'https://api.medplum.com/fhir/R4/Patient?_has:Observation:subject:performer:CareTeam.participant:Practitioner.name=bob' \
-H 'authorization: Bearer $ACCESS_TOKEN' \
-H 'content-type: application/fhir+json' \