# HAPI FHIR ValueSet Expand 為 0 的問題 ## 前言 某天同事收到了別人發過來的 issue,問題大致為 HAPI FHIR 已上傳 Snomed CT 的 Code 以及 IG Package,但是上傳範例上去時,ValueSet 會報找不到 Code 的錯誤 在經過一小番研究後,終於大致譜出 HAPI FHIR 的 ValueSet 尋找 Code 的方式,筆者認為這機制挺有意思的,必須記錄一下錯誤重現 (Error Reproduction) 以及目前找到的解決方法 ## 錯誤重現 - 首先,準備一台完全乾淨的 HAPI FHIR Server (這裡使用的是 v7.2.0 版本,記憶體建議 16 gb 以上) - 請記得在 `application.yaml` 先設定 `hibernate.search.enabled: true` ### 上傳 Terminology Code 以下的 Code 都是使用 HAPI FHIR [官方的 CLI 工具](https://hapifhir.io/hapi-fhir/docs/tools/hapi_fhir_cli.html)上傳 #### 上傳過程 - 上傳任何一個 Terminology Code 時,都會進行將 Code 儲存的動作,以下是 Code 儲存過程的 Log ![Code 儲存過程的 Log](https://hackmd.io/_uploads/BJ9KQ4nrJx.png) - 當出現 `All deferred concepts and relationships have now been synchronized to the database` 就代表 Code 儲存完成囉! ![Code 儲存完成的 Log](https://hackmd.io/_uploads/rk-iXEhB1x.png) :::danger ⚠️ 請等到 Code 完全處理完成,再進行下一個 Code 的上傳 ::: #### 上傳 Snomed CT ```! ./hapi-fhir-cli upload-terminology -d ${snomed-zip} -v r4 -t http://localhost:8080/fhir -u http://snomed.info/sct -s 10GB ``` - 若你遇到 Java heap space 的問題你可以試試看 ```! java -Xmx6g -jar ./hapi-fhir-cli.jar upload-terminology -d ${snomed-zip} -v r4 -t http://localhost:8080/fhir -u http://snomed.info/sct -s 10GB ``` #### 上傳 LOINC - 這裡使用的是 Loinc V2.73版本 ```! ./hapi-fhir-cli upload-terminology -d ${loinc-zip} -d ${loinc-properties} -v r4 -t http://localhost:8080/fhir -u http://loinc.org -s 10GB ``` - 其中 loinc-properties 的檔案內容如下 ```! loinc.hierarchy.file=AccessoryFiles/ComponentHierarchyBySystem/ComponentHierarchyBySystem.csv loinc.codesystem.version=2.73 ``` ### 展開 ValueSet - 以下展開的是 snomed 的 valueset - 開啟 postman - 網址輸入:`http://localhost:8080/fhir/ValueSet/$expand` - Method 選擇:`POST` - body 使用 json 並使用以下 resource ```json!= { "resourceType": "Parameters", "parameter": [ { "name": "valueSet", "resource": { "resourceType": "ValueSet", "compose": { "include": [ { "filter": [ { "property": "concept", "op": "is-a", "value": "399097000" } ] } ] } } } ] } ``` > 這裡展開的範例是醫查的 [SNOMED CT Anesthesia值集](https://hitstdio.ntunhs.edu.tw/imri/ValueSet-anesthesia-sct.html#root) - 展開結果,可以看到展開後的結果為 0 ```json!= { "resourceType": "ValueSet", "meta": { "extension": [ { "url": "http://hapifhir.io/fhir/StructureDefinition/valueset-expansion-message", "valueString": "ValueSet with URL \"Unidentified ValueSet\" was expanded using an in-memory expansion" } ] }, "status": "active", "compose": { "include": [ { "system": "http://snomed.info/sct", "filter": [ { "property": "concept", "op": "is-a", "value": "399097000" } ] } ] }, "expansion": { "identifier": "f906cf29-2b33-435e-9e61-9f24923ee7c3", "timestamp": "2024-07-07T14:38:24+00:00", "offset": 0, "parameter": [ { "name": "offset", "valueInteger": 0 }, { "name": "count", "valueInteger": 1000 } ] } } ``` ## 解決過程 ### ValueSet 展開需打開 hibernate.search.enabled 功能 - 由於筆者一開始是使用同事架好的 HAPI FHIR,怎麼試都找不到解決方法,回到家後,決定自己架一台測試,結果一用 ValueSet 的 $expand 功能卻跑出了以下錯誤 ![hibernate.search.enabled 未開啟](https://hackmd.io/_uploads/rkokB4nryx.png) - 要解決不能使用 $expand 功能的問題,請到 application.yaml將`hibernate.search.enabled` 選項開啟 ``` ### These settings will enable fulltext search with lucene or elastic hibernate.search.enabled: true ``` - 當你仔細看到這個設定時,會看到上面的註解`These settings will enable fulltext search with lucene or elastic`,看到這邊,筆者就發現不對勁,原來 ValueSet 的 Code 查詢方法是從 lucene 或 elasticsearch 來的 (預設是 lucene) ### ValueSet $expand 尋找 Code 的過程 以下是筆者大致猜測 ValueSet $expand 尋找 Code 的過程,若是想知道真實過程,還請大神們看 HAPI FHIR 的 Source Code 推導並分享分享 1. 進行 ValueSet $expand 動作 2. HAPI FHIR 會去找 Lucene index 的 code (展開為 0 大概是因為 Lucene 的 index 出錯) 3. 將 Lucene index 的 code 展開 4. 將 code 儲存至 trm_valueset_concept 的 table 內,以便後續使用 ![ValueSet $expand 尋找 Code 的過程](https://hackmd.io/_uploads/BkXSHE2BJe.png) :::info ℹ️ Lucene 是使用檔案系統進行 index 的,若你想找到 Lucene index 的檔案,可以將 /app/target/lucenefiles 給 volumn 出來 ::: ### 解決方案 Reindex Terminology 在 HAPI FHIR 的官方文件當中有提到 [Reindex Terminology](https://hapifhir.io/hapi-fhir/docs/tools/hapi_fhir_cli.html#reindex-terminology) 的指令: The reindex-terminology command may be used to recreate freetext indexes for terminology resources. 上面筆者推測是 Lucene 的 index 出錯了,所以重跑了這段指令看看,結果!!!expand 的結果就正常了 #### Reindex Terminology - 使用 hapi-fhir-cli 指令執行 reindex terminology ```! ./hapi-fhir-cli reindex-terminology -v r4 -t "http://localhost:8080/fhir" ``` - 執行後,HAPI FHIR 會出現準備重新 Index 多少資料的 Log ![開始 Reindex 的 Log](https://hackmd.io/_uploads/SJG2BVnr1e.png) - 過程中都會出現進度條的 Log,當完成時,會出現 Re-creating terminology freetext indexes took {time} ![Reindex 完成的 Log](https://hackmd.io/_uploads/SkgaB42r1e.png) #### 重新展開 ValueSet 重新執行[展開 ValueSet]後的結果如下(https://app.gitbook.com/o/ksml8wtewJVGJzK6ckE5/s/OLTFnZLfnxYlZrUiz9zr/#zhan-kai-valueset) ![重新展開 ValueSet 的結果](https://hackmd.io/_uploads/Ski1UEnSye.png) ## 參考資料 1. https://hapifhir.io/hapi-fhir/docs/tools/hapi_fhir_cli.html​ 2. https://hapifhir.io/hapi-fhir/docs/server_jpa/elastic.html ## Support Me 文件創作花費了很多心血製作,如果你覺得很有幫助 不妨贊助我一下喝杯咖啡唄,[Support Me](https://portaly.cc/Li070/support)