Cloud Healthcare API FHIR 搜尋實作功能具備高度可擴充性和效能,同時仍遵循 REST 和 FHIR 規格指南和限制。為協助達成此目標,FHIR 搜尋有以下屬性:
搜尋總數是預估值,直到最後一頁回傳為止。
fhir.search
方法傳回的搜尋結果包含搜尋總數 (Bundle.total
屬性),也就是搜尋中相符項目的總數。搜尋總數是預估值,直到傳回最後一頁搜尋結果為止。與最後一頁結果一併傳回的搜尋總數,是搜尋中所有相符項目的正確總和。搜尋結果會提供依序的向前分頁。如果還有更多搜尋結果要傳回,回應會包含分頁網址 (
Bundle.link.url
),可用於取得下一頁的結果。
基本用途
FHIR 搜尋可解決下列用途:
請參閱下列各節,瞭解這些用途的可行解決方案。
依序瀏覽
您可以建立低延遲應用程式,讓使用者依序瀏覽結果頁面,直到找到所需的項目為止。如果比對結果數量不多,使用者只要逐頁瀏覽即可找到所需的比對結果,不必略過結果,這時就能採用這項解決方案。如果您的使用情境需要使用者一次前往多個頁面,或向後瀏覽,請參閱「前往附近的頁面」。
只有在最後一頁的結果傳回後,這項解決方案才能提供準確的搜尋總數。不過,它可以提供每個結果網頁的近似搜尋總數。雖然精確的搜尋總數可能會是背景程序的必要條件,但一般來說,使用者通常只需要大約的搜尋總數。
工作流程
以下是這個解決方案的示例工作流程:
應用程式會呼叫
fhir.search
方法,該方法會傳回搜尋結果的第一頁。如果有更多結果要傳回,回應就會包含分頁網址 (Bundle.link.url
)。回應也會包含搜尋總數 (Bundle.total
)。如果要傳回的結果比初始回應多,搜尋總數就只是預估值。詳情請參閱「分頁和排序」一文。應用程式會顯示搜尋結果頁面、下一頁搜尋結果的連結 (如有),以及搜尋結果總數。
如果使用者想查看下一頁的結果,就會點選連結,導致系統呼叫分頁網址。如果有更多結果要傳回,回應就會包含新的分頁網址。回應也包含搜尋總數。如果有更多結果要傳回,這會是更新後的預估值。
應用程式會顯示新的搜尋結果頁面、下一頁搜尋結果的連結 (如有),以及搜尋結果總數。
重複執行上述兩個步驟,直到使用者停止搜尋或傳回最後一個結果頁面為止。
最佳做法
選擇適當的頁面大小,讓使用者輕鬆閱讀。視用途而定,每個網頁可能有 10 到 20 個相符項目。較小的網頁載入速度較快,且網頁上的連結過多可能會讓使用者難以管理。您可以使用 _count
參數控制頁面大小。
處理一組搜尋結果
您可以使用分頁網址,依序呼叫 fhir.search
方法,取得一組搜尋結果。如果搜尋結果數量不多,您可以繼續執行搜尋,直到沒有更多網頁可傳回為止,就能取得完整的結果。最後一頁的結果會顯示準確的搜尋總數。取得搜尋結果後,應用程式就能逐一讀取這些結果,並執行您需要的任何處理、分析或匯總作業。
請注意,如果搜尋結果數量龐大,可能無法在合理的時間內取得最後一頁搜尋結果 (以及正確的搜尋總數)。
工作流程
以下是這個解決方案的示例工作流程:
應用程式會呼叫
fhir.search
方法,該方法會傳回搜尋結果的第一頁。如果有更多結果要傳回,回應會包含分頁網址 (Bundle.link.url
)。如果還有其他結果要傳回,應用程式會呼叫先前步驟中的分頁網址,取得下一頁的搜尋結果。
應用程式會重複執行上述步驟,直到沒有任何結果可傳回或達到其他預先定義的限制為止。如果您已到達搜尋結果的最後一頁,搜尋總數就會正確顯示。
應用程式會處理搜尋結果。
視用途而定,應用程式可以執行下列任一操作:
- 請等到所有搜尋結果都收到後,再處理資料。
- 每次呼叫
fhir.search
時,收到資料就處理。 - 設定某種限制,例如傳回的符合項目數量或經過的時間長度。達到上限時,您可以處理資料,但不能處理資料或執行其他動作。
設計選項
以下是一些可能可縮短搜尋延遲時間的設計選項:
設定較大的頁面大小。使用
_count
參數設定較大的頁面大小,視用途而定,可能為 500 到 1,000。使用較大的網頁大小會增加每次擷取網頁的延遲時間,但可能會加快整體程序,因為擷取的網頁數量會減少,即可取得整組搜尋結果。限制搜尋結果數量。如果您只需要準確的搜尋總數 (不需要傳回資源內容),請將
fhir.search
方法的_elements
參數設為identifier
。與要求傳回完整 FHIR 資源相比,這可能會縮短搜尋查詢的延遲時間。詳情請參閱「限制在搜尋結果中傳回的欄位」。
需要預先載入和快取的用途
您可能需要使用超越簡單機制的功能,例如使用分頁網址依序呼叫 fhir.search
方法。其中一種做法是在應用程式和 FHIR 儲存庫之間建立快取層,在預先擷取及快取搜尋結果時維持工作階段狀態。應用程式可以將搜尋結果分組成 10 或 20 個相符項目的「應用程式頁面」。接著,應用程式就能根據使用者的選項,以直接且非順序的方式,快速為使用者提供這些小型應用程式網頁。如需這類工作流程的範例,請參閱「前往附近的頁面」一文。
前往附近的頁面
您可以建立低延遲解決方案,讓使用者瀏覽大量搜尋結果,直到找到所需的項目為止。它可擴充至幾乎無限的配對數量,同時維持低延遲,並讓資源消耗量增加幅度保持在相對較低的程度。使用者可以直接前往搜尋結果頁面,最多可前往或返回目前頁面預先設定的頁面數量。您可以為每個搜尋結果頁面提供預估搜尋總數。這項設計與 Google 搜尋的設計類似,可供您參考。
工作流程
圖 1 為此解決方案的示例工作流程。透過這個工作流程,每當使用者選取要查看的結果頁面時,應用程式就會提供附近頁面的連結。在這種情況下,應用程式會提供連結,連往從所選網頁往前或往後最多五個網頁,為了讓使用者能查看四個向前頁面,應用程式會在使用者選取結果頁面時,預先擷取另外 40 個相符項目。
圖 1. 應用程式會將搜尋結果分組成「應用程式頁面」,並將這些頁面快取後提供給使用者。
圖 1 說明這些步驟:
使用者在應用程式前端輸入搜尋查詢,並發起下列動作:
應用程式會呼叫
fhir.search
方法,預先擷取搜尋結果的第一頁。_count
參數設為 100,可讓回應的頁面大小保持相對較小,進而縮短回應時間。如果還有其他結果要傳回,回應中就會包含分頁網址 (Bundle.link.url
)。回應也包含搜尋總數 (Bundle.total
)。如果有更多結果要傳回,搜尋總數會是預估值。詳情請參閱「分頁和排序」一文。應用程式會將回應傳送至快取層。
在快取層中,應用程式會將回應中的 100 個相符項目分組為 10 個應用程式頁面,每個頁面包含 10 個相符項目。應用程式頁面是應用程式可向使用者顯示的部分相符項目。
應用程式會向使用者顯示應用程式頁面 1。應用程式頁面 1 包含應用程式頁面 2 至 10 的連結,以及預估搜尋總數。
使用者點選連結至不同應用程式頁面 (本例為應用程式頁面 10) 的連結,啟動下列動作:
應用程式會使用先前預先擷取功能傳回的分頁網址,呼叫
fhir.search
方法,以便預先擷取下一頁的搜尋結果。_count
參數設為 40,可從使用者的搜尋查詢中預先擷取接下來 40 個相符項目。40 個相符項目是指應用程式向使用者提供的下一個四個應用程式頁面。應用程式會將回應傳送至快取層。
在快取層中,應用程式會將回應中的 40 個相符項目分組為四個應用程式頁面,每個頁面包含 10 個相符項目。
應用程式會向使用者顯示應用程式頁面 10。應用程式頁面 10 包含應用程式頁面 5 至 9 的連結 (從應用程式頁面 10 往前五個應用程式頁面),以及應用程式頁面 11 至 14 的連結 (從應用程式頁面 10 往後四個應用程式頁面)。應用程式頁面 10 也包含預估搜尋總數。
只要使用者想繼續點按應用程式頁面連結,這個過程就會持續進行。請注意,如果使用者從目前的應用程式頁面瀏覽上一頁,且您已將所有附近的應用程式頁面快取,則可視使用情境選擇不執行新的預先載入作業。
這項解決方案快速又有效率,原因如下:
- 小型預先載入作業,甚至是更小型的應用程式頁面,都能快速處理。
- 快取的搜尋結果可減少對相同結果的多次呼叫需求。
- 無論搜尋結果數量有多大,這個機制仍可維持快速的速度。
設計選項
請根據您的用途考慮下列設計選項:
應用程式頁面大小。如果符合您的用途,應用程式頁面可以包含超過 10 個相符項目。請注意,較小的網頁載入速度較快,且網頁上的連結過多可能會讓使用者難以管理。
應用程式頁面連結數量。在本文建議的工作流程中,每個應用程式頁面都會傳回九個連結至其他應用程式頁面的連結:五個連結可直接從目前的應用程式頁面返回應用程式頁面,四個連結可直接從目前的應用程式頁面前往其他頁面。您可以根據使用情境調整這些數字。
最佳做法
只在必要時使用快取層。如果您設定快取層,請僅在應用程式需要時才使用。不需快取層的搜尋應略過快取層。
縮減快取大小。為節省資源,您可以清除舊的搜尋結果,同時保留用來取得結果的網頁網址,藉此縮減快取的大小。接著,您可以根據需要呼叫網頁網址,重新建構快取。請注意,多次呼叫相同分頁網址的結果可能會隨時間變更,因為 FHIR 儲存庫中的資源會在背景中建立、更新和刪除。清除快取的決定、清除方式,以及清除頻率,這些設計決策都取決於您的用途。
清除特定搜尋的快取內容。為節省資源,您可以從快取中完全移除非活動搜尋的結果。建議您先移除閒置最久的搜尋。請注意,如果已清除的搜尋重新啟用,可能會導致錯誤狀態,迫使快取層重新啟動搜尋。
前往任何頁面
如果您希望使用者能夠前往搜尋結果中的任何網頁 (而非僅限於目前網頁附近的網頁),可以使用類似於「前往附近網頁」一節所述的快取層。不過,如果您想讓使用者前往搜尋結果中的任何應用程式頁面,就必須預先擷取並快取所有搜尋結果。在搜尋結果數量較少的情況下,這可能會發生。當搜尋結果數量龐大時,預先擷取所有搜尋結果可能不切實際或無法執行。即使搜尋結果數量不多,預先擷取的時間可能會比使用者合理的等待時間還要長。
工作流程
設定類似「前往附近的頁面」的工作流程,但有一個重要差異:應用程式會在背景持續預先擷取搜尋結果,直到所有符合項目都傳回或達到其他預先定義的限制為止。
以下是這個解決方案的示例工作流程:
應用程式會呼叫
fhir.search
方法,從使用者的搜尋查詢中預先擷取搜尋結果的第一頁。如果有更多結果要傳回,回應會包含分頁網址 (Bundle.link.url
)。回應中也會包含搜尋總數 (Bundle.total
)。如果有更多結果要傳回,這項數字是預估值。應用程式會將回應中的相符項目分組成每組 20 個相符項目的應用程式頁面,並儲存在快取中。應用程式頁面是應用程式可向使用者顯示的幾個相符項目組合。
應用程式會向使用者顯示第一個應用程式頁面。應用程式頁面包含快取應用程式頁面的連結,以及預估搜尋總數。
如果還有其他結果要傳回,應用程式會執行下列操作:
- 呼叫先前預先擷取作業傳回的分頁網址,以取得下一頁的搜尋結果。
- 將回應中的比對結果分組成每組 20 個比對結果的應用程式頁面,並儲存在快取中。
- 透過新的連結,重新整理使用者目前正在查看的應用程式頁面,連結會連往新預先擷取及快取的應用程式頁面。
應用程式會重複執行上述步驟,直到沒有任何結果可傳回或達到其他預先定義的限制為止。系統會傳回準確的搜尋總數,以及最後一頁的搜尋結果。
在應用程式在背景預先擷取及快取相符項目的同時,使用者可以繼續點選快取頁面的連結。
設計選項
請根據您的用途考慮下列設計選項:
應用程式頁面大小。如果符合您的用途,應用程式頁面可以包含 20 個以上的相符項目,也可以少於 20 個。請注意,較小的網頁載入速度較快,且網頁上如果有太多連結,使用者可能會難以管理。
重新整理搜尋總數。在應用程式在背景預先擷取及快取搜尋結果的同時,您可以向使用者顯示逐漸更準確的搜尋總數。如要這麼做,請設定應用程式執行下列操作:
在設定的間隔中,從快取層中的最新預先擷取內容取得搜尋總數 (
Bundle.total
屬性)。這是目前對搜尋總量的最佳預估值。向使用者顯示搜尋總數,並指出這是預估值。請根據用途決定此重新整理的頻率。辨識快取層的搜尋總數是否正確。也就是說,搜尋總數來自搜尋結果的最後一頁。當搜尋結果頁面結束時,應用程式會顯示搜尋總數,並向使用者指出搜尋總數是否正確。接著,應用程式就會停止從快取層取得搜尋總數。
請注意,如果比對結果數量龐大,背景預先擷取和快取作業可能無法在使用者完成搜尋工作階段前,取得搜尋結果的最後一頁 (以及準確的搜尋總數)。
最佳做法
去除重複的內含資源。如果您在預先擷取及快取搜尋結果時使用
_include
和_revinclude
參數,建議您在每次預先擷取後,重複使用快取中的資源。這麼做可減少快取大小,進而節省記憶體。將相符項目分組至應用程式頁面時,請在每個應用程式頁面中加入適當的所附資源。詳情請參閱「在搜尋結果中加入其他資源」。設定預先載入和快取的上限。搜尋結果數量龐大,因此預先擷取所有搜尋結果可能不切實際或無法執行。建議您設定預先載入搜尋結果的數量上限。這樣一來,快取的大小就會維持在可控範圍內,有助於節省記憶體。舉例來說,您可以將快取大小限制為 10,000 或 20,000 個比對項目。或者,您可以限制預先載入的網頁數量,或是設定時間限制,以便在時間到期後停止預先載入。您設定的限制類型和設定方式是設計決策,取決於您的用途。如果在傳回所有搜尋結果之前就達到限制,請考慮向使用者說明這點,包括搜尋總數仍是預估值。
前端快取
應用程式前端 (例如網路瀏覽器或行動應用程式) 可提供部分搜尋結果快取,做為在架構中引入快取層的替代方案。這個方法可利用 AJAX 呼叫並儲存搜尋結果和/或分頁網址,提供前一個頁面或導覽記錄中的任何頁面導覽功能。以下是這種方法的部分優點:
- 這可能比快取層耗用較少的資源。
- 因為它會將快取作業分散到多個用戶端,因此更具可擴充性。
- 這樣一來,您就能更輕鬆地判斷何時不再需要快取資源,例如使用者關閉分頁或離開搜尋介面時。
常見的最佳做法
以下是適用於本文件中所有解決方案的最佳做法。
請注意,頁面數量可能小於 _count 值。在某些情況下,搜尋結果可能會傳回比您指定的
_count
值少的網頁。舉例來說,如果您指定的網頁大小特別大,就可能發生這種情況。如果搜尋結果傳回的頁面小於_count
值,且應用程式使用快取層,您可能需要決定是否要 (1) 在應用程式頁面上顯示比預期少的結果,或 (2) 擷取更多結果,以便取得足夠的結果來完成應用程式頁面。詳情請參閱「分頁和排序」一文。重試可重試的 HTTP 要求錯誤。您的應用程式應預期可重試的 HTTP 要求錯誤,例如
429
或500
,並在收到這些錯誤後重試。
評估用途
實作前往任何網頁、取得準確的搜尋總數,以及更新預估總數等功能,會增加應用程式的複雜度和開發成本。這些功能也會增加延遲時間,並提高使用 Google Cloud資源的金錢成本。建議您仔細評估用途,確保這些功能的價值足以抵銷成本。請考量以下事項:
前往任一頁面:使用者通常不需要前往特定網頁,而是從目前的網頁前往多個網頁。在大多數情況下,導覽至附近的頁面就足夠了。
準確的搜尋總數。隨著 FHIR 儲存庫中的資源建立、更新和刪除,搜尋總數可能會有所變動。因此,搜尋總數在傳回當下 (包含搜尋結果的最後一頁) 時是正確的,但隨著時間推移,可能會變得不正確。因此,精確的搜尋總數對應用程式可能沒有太大價值,這取決於您的用途。