Skip to main content

$search

$search(resourceTypeOrQuery?, params?, options?) -> value
Compact type signature<s-o?o?:x>

If resourceTypeOrQuery is omitted, the current context value is used.

Execution
AsyncCan run in parallel

This helper performs FHIR server work asynchronously. Independent calls can start together when they wait on the server. See Parallelism And Async Evaluation and Async And Concurrency.

Documentation​

Requires a configured FHIR server base URL.

Multi-server connections

This function uses the default FHIR server unless $useFhirServer() has been called in the current expression block. See Multi-server connections for details.

$search(resourceTypeOrQuery, params?, options?) performs a FHIR search. The canonical form is a resource type as the first argument and a params object as the second argument. A full query string remains supported when that is more convenient.

Zero, one, or many matches are all valid outcomes.

Return shapes​

  • By default, $search() returns the raw FHIR searchset Bundle returned by the server for that request. In most cases this is the first page of results.
  • If you pass {"fetchAll": true}, $search() follows pagination and returns a flattened array of resources collected from Bundle.entry[].resource across the fetched pages instead of a Bundle.
  • If you also pass {"transform": function($resource, $mode, $index, $entry) { ... }}, that function runs once for each raw Bundle.entry[].resource before the final array is returned.

When fetchAll is enabled, every resource present in Bundle.entry[].resource is included in the returned array. If your search uses _include or _revinclude, included resources are part of that array when the server returns them. This is different from single-match helpers such as $literal() and $resolve(), which enforce match-specific behavior for their own results.

Transform function behavior​

Availability:

  • Community v3.2.0+
  • Enterprise v3.2.0+.

transform is supported only when fetchAll is true.

Use a function shaped as function($resource, $mode, $index, $entry) { ... }.

Only the first parameter, $resource, is required. Your function can declare one, two, three, or four parameters.

The arguments are passed to your function by position - the actual names of the parameters don't matter. So the resource will be passed as the first argument even if you don't call it $resource, and mode will be passed to the second argument even if you don't call it $mode.

  • If you only need the resource, function($resource) { ... } is enough.

  • If you need the resource and the mode, use function($resource, $mode) { ... }.

  • If you need the resource and the entry, you still need to keep the middle positions: function($resource, $unusedMode, $unusedIndex, $entry) { ... }.

  • $resource is the current Bundle.entry[].resource.

  • $mode is Bundle.entry.search.mode when the server provides it, such as match or include. If the server does not provide search.mode, $mode is undefined.

  • $index is the zero-based running index across raw fetched resources before filtering.

  • $entry is the original Bundle.entry object.

If the function returns undefined, that resource is left out of the final array. If the function throws or rejects, the overall search fails immediately.

Zero results​

Zero results are valid.

  • In default mode, the server can return a searchset Bundle with no entry items.
  • In fetchAll mode, $search() returns an empty array.

Supported argument forms​

  • Structured query: $search("Patient", {"identifier": "http://fhir.acme.health/identifier/member-id|" & identifiers.memberId})
  • String query: $search("Patient?identifier=http://fhir.acme.health/identifier/member-id|" & identifiers.memberId)

Supported options​

  • fetchAll: follow pagination and return an array of resources collected from Bundle.entry[].resource instead of the server-returned Bundle
  • transform: when fetchAll is enabled, run function($resource, $mode, $index, $entry) { ... } once for each raw Bundle.entry[].resource; return undefined to leave an item out of the final array
  • maxResults: when fetchAll is enabled, override the default per-call safety cap and stop with an error before collecting more than this many resources across fetched pages
  • asPost: send the search to the FHIR _search endpoint using POST (see GET and POST variants for FHIR search). Default is false (uses GET)
  • noCache: bypass cached responses for this request. This forces a fresh interaction even if the request is already cached.

When fetchAll is enabled, $search() uses a default safety cap of 10000 collected resources. Use maxResults to override that cap for the current call. There is no current fume-community or fume environment-variable setting for this limit.

When transform is enabled, maxResults still counts raw fetched resources before any transform-based filtering. Included resources that your function later leaves out still count toward that cap.

Params object behavior​

  • Primitive values become a single FHIR search parameter.
  • Comma-separated strings stay a single parameter value, which is the FHIR-style for OR pattern for a single parameter.
  • Array values become repeated parameters such as identifier=a&identifier=b, which is the practical FHIR-style AND pattern.

Examples​

Search for matching resources​

Input

This example uses the full patient-summary example input. The expression reads the non-FHIR identifiers.memberId source field and combines it with a fixed FHIR identifier system in the search expression.

Example input

JSON
{
"patientId": "pat-0001",
"name": {
"given": "Avery",
"family": "Reed",
"display": "Avery Reed"
},
"birthDate": "1990-06-12",
"sex": "female",
"primaryCareTeam": {
"organization": "ExampleCare",
"facility": "ExampleCare Clinic",
"practitioner": {
"practitionerId": "prac-4001",
"display": "Jordan Kim"
}
},
"identifiers": {
"memberId": "mbr-3001",
"recordNumber": "rec-5001"
},
"tags": [
"demo",
"fictional"
],
"_xmlTagName": "patientSummary"
}

Expression

$search("Patient", {"identifier": "http://fhir.acme.health/identifier/member-id|" & identifiers.memberId})

The result below shows the default return shape: the raw searchset Bundle returned by the server. If nothing matches, the same mode can return a valid Bundle with no entry items.

Result

{
"resourceType": "Bundle",
"type": "searchset",
"total": 1,
"entry": [
{
"resource": {
"resourceType": "Patient",
"id": "pat-0001"
}
}
]
}

Fetch all resources returned across pages​

Input

This example uses the same patient-summary source input and switches only the options object.

Example input

JSON
{
"patientId": "pat-0001",
"name": {
"given": "Avery",
"family": "Reed",
"display": "Avery Reed"
},
"birthDate": "1990-06-12",
"sex": "female",
"primaryCareTeam": {
"organization": "ExampleCare",
"facility": "ExampleCare Clinic",
"practitioner": {
"practitionerId": "prac-4001",
"display": "Jordan Kim"
}
},
"identifiers": {
"memberId": "mbr-3001",
"recordNumber": "rec-5001"
},
"tags": [
"demo",
"fictional"
],
"_xmlTagName": "patientSummary"
}

Expression

$search("Patient", {"identifier": "http://fhir.acme.health/identifier/member-id|" & identifiers.memberId}, {"fetchAll": true})

This mode returns an array of resources instead of a Bundle. The array contains every resource present in Bundle.entry[].resource across the fetched pages, so _include and _revinclude results are included when the server returns them. If nothing matches, the result is [] (empty array).

Result

[
{
"resourceType": "Patient",
"id": "pat-0001"
}
]

Fetch a patient with _include + _revinclude and keep only the included resources​

Input

This example uses the patient-summary example input. The search loads one patient, asks for the patient's general practitioner and related encounters, then uses transform to leave the patient itself out of the final array.

Example input

JSON
{
"patientId": "pat-0001",
"name": {
"given": "Avery",
"family": "Reed",
"display": "Avery Reed"
},
"birthDate": "1990-06-12",
"sex": "female",
"primaryCareTeam": {
"organization": "ExampleCare",
"facility": "ExampleCare Clinic",
"practitioner": {
"practitionerId": "prac-4001",
"display": "Jordan Kim"
}
},
"identifiers": {
"memberId": "mbr-3001",
"recordNumber": "rec-5001"
},
"tags": [
"demo",
"fictional"
],
"_xmlTagName": "patientSummary"
}

Expression

$search(
"Patient",
{
"_id": patientId,
"_include": "Patient:general-practitioner",
"_revinclude": "Encounter:patient"
},
{
"fetchAll": true,
"transform": function($resource, $mode, $index, $entry) {
$mode = "include"
? {
"index": $index,
"resourceType": $resource.resourceType,
"id": $resource.id,
"mode": $mode,
"fullUrl": $entry.fullUrl
}
}
}
)

The function sees the patient row and the related included and revincluded rows. It returns undefined for the patient match (since mode does not equal include for that entry), so the final array keeps only the related resources. Raw-resource indexing and maxResults counting still include the patient row even though it does not appear in the final result.

Result

[
{
"index": 1,
"resourceType": "Practitioner",
"id": "prac-4001",
"mode": "include",
"fullUrl": "https://fhir.acme.health/Practitioner/prac-4001"
},
{
"index": 2,
"resourceType": "Encounter",
"id": "enc-1001",
"mode": "include",
"fullUrl": "https://fhir.acme.health/Encounter/enc-1001"
}
]