Skip to main content

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.

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'
await medplum.searchResources('Observation', {
'patient.name': 'homer',
});

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'
await medplum.searchResources('Observation', {
'subject:Patient.name': 'homer',
});

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
await medplum.searchResources('Observation', {
'encounter:Encounter.service-provider.name': 'Kaiser',
});

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.

Resource Type Ambiguity

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
await medplum.searchResources('Patient', {
_has: 'Observation:subject:code=8867-4',
});

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
await medplum.searchResources('Specimen', {
_has: 'DiagnosticReport:specimen:_has:Procedure:reason-reference:date=2023-11-12',
});

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
await medplum.searchResources('Patient', {
_has: 'Observation:subject:performer:CareTeam.participant:Practitioner.name=bob',
});