You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/* function that calculates the absolute diff between dates in milliseconds */
$dateDiffMillis := function($date1, $date2){($abs($toMillis($date1)-$toMillis($date2)))};
/* function that fetches resources above and below a requested date and returns them sorted by proximity /
$getClosestResources := function($resourceType, $date, $searchParam, $elementName) {(
/ get pages from above and below the date /
$geBundle := $search($resourceType, {$searchParam: 'ge' & $date, '_sort': $searchParam, '_count': $pageSize, '_elements': $elementName});
$leBundle := $search($resourceType, {$searchParam: 'le' & $date, '_sort': '-' & $searchParam, '_count': $pageSize, '_elements': $elementName});
/ sort the results by absolute diff from the selected date */
[$geBundle.entry.resource, $leBundle.entry.resource]^($dateDiffMillis($date, $lookup($, $elementName)));
)};
/* recursive function that adds a single new resource to an accumulating list /
/ educational note: /
/ note that the self-call is at the final step of the function. /
/ this is called "tail recursion" and it helps prevent stack overflow. /
/ see: https://docs.jsonata.org/programming#tail-call-optimization-tail-recursion/
$addResource := function($resourceType, $searchParam, $elementName, $accumulating, $iterationCounter){(
/ reset counter to 1 if not stated otherwise /
$iterationCounter := $exists($iterationCounter) ? $iterationCounter : 1;
/ initialize an empty list if accumulator not passed /
$accumulating := $exists($accumulating) ? $accumulating : [];
/ generate a new random date /
$randomDate := $newRandomDate($minDate, $maxDate);
/ get list of patients closest to the random date by birthday, sorted by proximity /
$searchResults := $getClosestResources($resourceType, $randomDate, $searchParam, $elementName);
/ get the closest one not collected yet /
$selection := $searchResults[$not(id in $accumulating)][0];
/ check the results /
$exists($selection) ? (
/ found a new patient - add its id to the list and return the updated list /
[$accumulating, $selection.id]
) : (
/ no new patient found for this date /
/ if we have reached max iterations - stop looking /
$iterationCounter >= $maxRetriesForNewResource ? (
/ return accumulated list as-is /
$accumulating
) : (
/ not reached max iterations - try again with a new random date /
$addResource($resourceType, $searchParam, $elementName, $accumulating, $iterationCounter + 1)
/ ^ this is the "tail call" */
)
)
)};
/* wrapper function that does the collection of the list of resources /
$collectResources := function($resourceType, $amountToCollect, $minDate, $maxDate, $searchParam, $elementName){(
/ iteration function that adds resources recursively, as long as: /
/ 1. the previous step succeeded in finding a new resource /
/ 2. the requested amount hasn't been collected yet /
$iterator := function($currentList, $previousList){(
$exists($currentList) and ($count($currentList) = $count($previousList) or $count($currentList) >= $amountToCollect) ? (
/ the stop condition is met - return list and stop iterating /
$currentList
) : (
/ try to add one patient and continue /
$updatedList := $addResource($resourceType, $searchParam, $elementName, $currentList);
/ tail call /
$iterator($updatedList, $currentList)
)
)};
/ call the iterator with empty initial lists */
$ids := $iterator();
/* transform the list of resource id's to a list of references (ready for $resolve) */
$ids.($join([$resourceType, $], '/'))
)};
/call the wrapper function with relevant keys, values will come from input/
/$collectResources(resourceType, amountToCollect, "2000-01-01", "2020-01-01", searchParam, elementName)/
The below map and input wont work as expected.
Also, try, try.dev and rambam servers react diffrently
fume map
`(
/* global parameters */
$pageSize := 10;
$maxRetriesForNewResource := 10;
/*****************/
/* date generator function */
$newRandomDate := function($min, $max){(
$minMs := $toMillis($min);
$maxMs := $toMillis($max);
$diffMs := $maxMs - $minMs;
$randomMs := $random() * $diffMs;
$fromMillis(($minMs + $randomMs),'[Y0001]-[M01]-[D01]');
)};
/* function that calculates the absolute diff between dates in milliseconds */
$dateDiffMillis := function($date1, $date2){($abs($toMillis($date1)-$toMillis($date2)))};
/* function that fetches resources above and below a requested date and returns them sorted by proximity /$lookup($ , $elementName)));
$getClosestResources := function($resourceType, $date, $searchParam, $elementName) {(
/ get pages from above and below the date /
$geBundle := $search($resourceType, {$searchParam: 'ge' & $date, '_sort': $searchParam, '_count': $pageSize, '_elements': $elementName});
$leBundle := $search($resourceType, {$searchParam: 'le' & $date, '_sort': '-' & $searchParam, '_count': $pageSize, '_elements': $elementName});
/ sort the results by absolute diff from the selected date */
[$geBundle.entry.resource, $leBundle.entry.resource]^($dateDiffMillis($date,
)};
/* recursive function that adds a single new resource to an accumulating list /
/ educational note: /
/ note that the self-call is at the final step of the function. /
/ this is called "tail recursion" and it helps prevent stack overflow. /
/ see: https://docs.jsonata.org/programming#tail-call-optimization-tail-recursion /
$addResource := function($resourceType, $searchParam, $elementName, $accumulating, $iterationCounter){(
/ reset counter to 1 if not stated otherwise /
$iterationCounter := $exists($iterationCounter) ? $iterationCounter : 1;
/ initialize an empty list if accumulator not passed /
$accumulating := $exists($accumulating) ? $accumulating : [];
/ generate a new random date /
$randomDate := $newRandomDate($minDate, $maxDate);
/ get list of patients closest to the random date by birthday, sorted by proximity /
$searchResults := $getClosestResources($resourceType, $randomDate, $searchParam, $elementName);
/ get the closest one not collected yet /
$selection := $searchResults[$not(id in $accumulating)][0];
/ check the results /
$exists($selection) ? (
/ found a new patient - add its id to the list and return the updated list /
[$accumulating, $selection.id]
) : (
/ no new patient found for this date /
/ if we have reached max iterations - stop looking /
$iterationCounter >= $maxRetriesForNewResource ? (
/ return accumulated list as-is /
$accumulating
) : (
/ not reached max iterations - try again with a new random date /
$addResource($resourceType, $searchParam, $elementName, $accumulating, $iterationCounter + 1)
/ ^ this is the "tail call" */
)
)
)};
/* wrapper function that does the collection of the list of resources /
$collectResources := function($resourceType, $amountToCollect, $minDate, $maxDate, $searchParam, $elementName){(
/ iteration function that adds resources recursively, as long as: /
/ 1. the previous step succeeded in finding a new resource /
/ 2. the requested amount hasn't been collected yet /
$iterator := function($currentList, $previousList){(
$exists($currentList) and ($count($currentList) = $count($previousList) or $count($currentList) >= $amountToCollect) ? (
/ the stop condition is met - return list and stop iterating /
$currentList
) : (
/ try to add one patient and continue /
$updatedList := $addResource($resourceType, $searchParam, $elementName, $currentList);
/ tail call /
$iterator($updatedList, $currentList)
)
)};
/ call the iterator with empty initial lists */
$ids := $iterator();
)};
/call the wrapper function with relevant keys, values will come from input/
/$collectResources(resourceType, amountToCollect, "2000-01-01", "2020-01-01", searchParam, elementName)/
/* testing the function: */
$minDate := '1950-01-01';
$maxDate := $now();
$collectResources('Patient', 7, $minDate, $maxDate, 'birthdate', 'birthDate');
)`
fume input
{ "resourceType": "Patient", "amountToCollect": 7, "minDate": "2000-01-01", "maxDate": "2020-01-01", "searchParam": "birthdate", "elementName": "birthDate" }
fume error
{ "__isFumeError": true, "message": "Request failed with status code 500", "code": "ERR_BAD_RESPONSE", "name": "AxiosError", "token": "search", "cause": "", "position": 4489 }
console error
_header: 'GET /csp/healthshare/rambam/fhir/r4/Patient?_count=10&birthdate=ge1953-10-01&_sort=birthdate&_elements=birthDate HTTP/1.1\r\n' + 'Accept: application/fhir+json;fhirVersion=4.0\r\n' + 'Content-Type: application/fhir+json;fhirVersion=4.0\r\n' + 'User-Agent: axios/1.6.7\r\n' + 'Accept-Encoding: gzip, compress, deflate, br\r\n' + 'Host: ec2-3-124-79-139.eu-central-1.compute.amazonaws.com:52773\r\n' + 'Connection: keep-alive\r\n' + '\r\n', _keepAliveTimeout: 0, _onPendingData: [Function: nop], agent: [Agent], socketPath: undefined, method: 'GET', maxHeaderSize: undefined, insecureHTTPParser: undefined, joinDuplicateHeaders: undefined, path: '/csp/healthshare/rambam/fhir/r4/Patient?_count=10&birthdate=ge1953-10-01&_sort=birthdate&_elements=birthDate',
The text was updated successfully, but these errors were encountered: