VI.FUME
22 JSONata進階操作($merge, $exists, $zip, $function...)
前面講了一整卡車的JSONata,今天要把剩下比較進階的部分講完,
這部分的內容有些並不存在於FUME的Documentation中,但經筆者測試FUME完全相容於JSONata,請大家放心使用
可以先概述一下,之所以開始碰觸到這些較進階的操作主要是因為想要簡化輸入的資料欄位,比如說sequence序列這種流水號,
或是部分值集的對應與value[x]等相同欄位的處理方式,實際在實作時摸索會遇到很多想不到的問題,
這幾個問題都還滿令人頭痛的,當初在東找西找想出來解決方法,以經驗來說,目前遇到最頭痛的應該還是值集搜尋與代碼對應這一部分
因為過大的值集與代碼系統無法靠JSONata的物件內嵌(其實可以,但沒有意義),但若使用stateless模式又不能讓代碼搜尋變得可行,
在今天正式開始前要先來思考一個問題:
是簡化輸入比較好,還是加速編譯轉換效率?
筆者的答案目前是選擇前者,對第一線醫事人員來說,能盡量簡化輸入就簡化,在不影響臨床內容呈現的範圍內達成最小的輸入內容,
至於要往哪些方向去簡化,我們放到後面再談。
今天講的主要會是物件類的方法,對於操作一個具有複合資料內容的物件/變數來說非常實用。
$keys()
這個function可以幫你標出一個物件裡面的key值,但要注意會因為項次重複,就是正常的把所有內含的key值(屬性項名稱)拿出來
假設今天有一個輸入:
#INPUT
"phones": [
{
"type": "HOME",
"number": "+1 (407) 8372859"
},
{
"type": "CELL",
"number": "+1 (305) 9831195"
}
],
在JSONata/FUME中撰寫:
#FUME
phones.$keys()
輸出
#FHIR
[
"type",
"number",
"type",
"number"
]
$lookup()
這個function可以幫你找物件中指定key值的值,和$keys算是互補
和剛剛的keys用法非常類似,稍微變形了一下:
輸入和剛才的範例相同
#INPUT
"phones": [
{
"type": "HOME",
"number": "+1 (407) 8372859"
},
{
"type": "CELL",
"number": "+1 (305) 9831195"
}
],
在JSONata/FUME中撰寫:
#FUME
phones.$lookup('type')
輸出
#FHIR
[
"HOME",
"CELL"
]
$spread()
這個function可以幫你把物件內的所有key-value pair都分離出來成為單一個元素,
輸入和剛才的範例相同
#INPUT
"phones": [
{
"type": "HOME",
"number": "+1 (407) 8372859"
},
{
"type": "CELL",
"number": "+1 (305) 9831195"
}
],
在JSONata/FUME中撰寫:
#FUME
phones.$spread()
輸出
#FHIR
[
{
"type": "HOME"
},
{
"number": "+1 (407) 8372859"
},
{
"type": "CELL"
},
{
"number": "+1 (305) 9831195"
}
]
$merge()
這個function可以把兩個物件合併起來,某種程度上配合條件判斷式可以解決value[x]等相同項的排他問題,
在JSONata/FUME中撰寫:
#FUME
$result := (
$observation_main := (
InstanceOf: Observation
* id = "obs-test"
);
$observation_str := (
InstanceOf: Observation
* valueString = "test"
);
$observation := $merge([$observation_main, $observation_str]);
)
#FHIR
{
"resourceType": "Observation",
"id": "obs-test",
"valueString": "test"
}
這只是$merge的其中一種用法,結合FLASH語句,可以自由的把不同的FHIR描述並在一起,
(注意,如果合併的屬性項並不符合該Resource所允許的,會報錯)
$exists()
這個其實之前講過了,這邊要補充一下:
#INPUT
{
"mrn": ""
}
#FUME
$exists(mrn) ? "true" : "false"
#FHIR
true
$exists檢查的並不是屬性項內有沒有值,而是有沒有這個屬性項
如果你想要檢查上面的需求,可以用:
#FUME
$boolean(mrn)
$map()
用來做映射的function,結構為$map(array, function),
可以看到這個function內置了另一個function,意思是對這個array的每個元素都套用後面的function,
如:
#FUME
$map([1,2,3], function($v) { $v * 2 })
#FHIR
[2, 4, 6]
對這個array[1,2,3] 每個元素執行function($v * 2)
$zip()
在JSONata之中相對進階的function,用來處理矩陣轉置:
#FUME
$zip([1,2,3], [4,5,6])
#FHIR
[[1,4] ,[2,5], [3,6]]
在FHIR裡面會比較少用到。
至於$function()是自定義函式,就像上面$map內嵌的function,
可以自己嘗試一下使用的方法與搭配。
其他function如$sift()、$reduce等function筆者在實作IG轉換到目前為止還沒有應用過,
上面包含的$map()就已經能處理大多數簡化操作了,後面實作的時候會有比較詳細的例子來說
明天來講一下FUME裡面可以與FHIR Server協作的function部分,正因為這個功能讓整個FUME的可用性變得非常高,
唯一可惜的地方是stateless由於沒有與FHIR Server連動,這部分就變得不可用了。