$search
$search(resourceTypeOrQuery?, params?, options?) -> value<s-o?o?:x>If resourceTypeOrQuery is omitted, the current context value is used.
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.
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 searchsetBundlereturned 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 fromBundle.entry[].resourceacross the fetched pages instead of aBundle. - If you also pass
{"transform": function($resource, $mode, $index, $entry) { ... }}, that function runs once for each rawBundle.entry[].resourcebefore 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) { ... }. -
$resourceis the currentBundle.entry[].resource. -
$modeisBundle.entry.search.modewhen the server provides it, such asmatchorinclude. If the server does not providesearch.mode,$modeisundefined. -
$indexis the zero-based running index across raw fetched resources before filtering. -
$entryis the originalBundle.entryobject.
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
Bundlewith noentryitems. - In
fetchAllmode,$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 fromBundle.entry[].resourceinstead of the server-returnedBundletransform: whenfetchAllis enabled, runfunction($resource, $mode, $index, $entry) { ... }once for each rawBundle.entry[].resource; returnundefinedto leave an item out of the final arraymaxResults: whenfetchAllis enabled, override the default per-call safety cap and stop with an error before collecting more than this many resources across fetched pagesasPost: send the search to the FHIR_searchendpoint using POST (see GET and POST variants for FHIR search). Default isfalse(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
ORpattern for a single parameter. - Array values become repeated parameters such as
identifier=a&identifier=b, which is the practical FHIR-styleANDpattern.
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
{
"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
{
"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
{
"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"
}
]