La implementación de la búsqueda de FHIR de la API de Cloud Healthcare es altamente escalable y de buen rendimiento, a la vez que sigue los lineamientos y las limitaciones de REST y la especificación de FHIR. Para lograr esto, la búsqueda de FHIR tiene las siguientes propiedades:
El total de búsquedas es una estimación hasta que se muestra la última página. Los resultados de la búsqueda que muestra el método
fhir.search
incluyen el total de la búsqueda (la propiedadBundle.total
), que es la cantidad total de coincidencias en la búsqueda. El total de la búsqueda es una estimación hasta que se muestra la última página de resultados de la búsqueda. El total de la búsqueda que se muestra con la última página de resultados es una suma precisa de todas las coincidencias de la búsqueda.Los resultados de la búsqueda proporcionan una paginación secuencial y hacia adelante. Cuando hay más resultados de la búsqueda para mostrar, la respuesta incluye una URL de paginación (
Bundle.link.url
) para obtener la siguiente página de resultados.
Casos de uso básicos
La búsqueda de FHIR proporciona soluciones para los siguientes casos de uso:
- Navega de forma secuencial. Un usuario explora de forma secuencial una cantidad limitada de páginas de resultados de la búsqueda. Se muestra un total estimado de búsquedas con cada página.
- Procesa un conjunto de resultados de la búsqueda. Una app obtiene un conjunto de resultados de la búsqueda, los lee y procesa los datos.
Consulta las siguientes secciones para conocer las posibles soluciones para estos casos de uso.
Cómo navegar de forma secuencial
Puedes compilar una aplicación de baja latencia que permita al usuario avanzar de forma secuencial por las páginas de resultados hasta que encuentre la coincidencia que desea. Esta solución es factible si la cantidad de coincidencias es lo suficientemente pequeña como para que el usuario pueda encontrar la coincidencia deseada navegando página por página sin omitir resultados. Si tu caso de uso requiere que los usuarios naveguen hacia adelante varias páginas a la vez o hacia atrás, consulta Cómo navegar a una página cercana.
Esta solución no puede proporcionar un total de búsqueda preciso hasta que se muestra la última página de resultados. Sin embargo, puede proporcionar un total de búsqueda aproximado con cada página de resultados. Si bien un total de búsqueda preciso podría ser un requisito para un proceso en segundo plano, un total de búsqueda aproximado suele ser adecuado para un usuario humano.
Flujo de trabajo
Este es un ejemplo de flujo de trabajo para esta solución:
Una app llama al método
fhir.search
, que muestra la primera página de los resultados de la búsqueda. La respuesta incluye una URL de paginación (Bundle.link.url
) si hay más resultados que mostrar. La respuesta también incluye el total de la búsqueda (Bundle.total
). Si hay más resultados que mostrar que en la respuesta inicial, el total de la búsqueda es solo una estimación. Para obtener más información, consulta Paginación y ordenamiento.La app muestra la página de resultados de la búsqueda, un vínculo a la página siguiente de resultados (si la hay) y el total de la búsqueda.
Si el usuario quiere ver la siguiente página de resultados, hace clic en el vínculo, lo que genera una llamada a la URL de paginación. La respuesta incluye una nueva URL de paginación si hay más resultados para mostrar. La respuesta también incluye el total de búsquedas. Esta es una estimación actualizada si hay más resultados para mostrar.
La app muestra la nueva página de resultados de la búsqueda, un vínculo a la página siguiente de resultados (si la hay) y el total de la búsqueda.
Los dos pasos anteriores se repiten hasta que el usuario deja de buscar o se muestra la última página de resultados.
Práctica recomendada
Elige un tamaño de página adecuado para que una persona lo lea sin dificultad. Según tu caso de uso, puede ser de 10 a 20 coincidencias por página. Las páginas más pequeñas se cargan más rápido y puede ser difícil para un usuario administrar demasiados vínculos en una página. Controlas el tamaño de la página con el parámetro _count
.
Procesa un conjunto de resultados de la búsqueda
Para obtener un conjunto de resultados de la búsqueda, puedes realizar llamadas sucesivas al método fhir.search
con la URL de paginación. Si la cantidad de resultados de la búsqueda es lo suficientemente pequeña, puedes obtener un conjunto completo de resultados si continúas hasta que no haya más páginas para mostrar. En la última página de resultados, se incluye un total de búsquedas preciso. Después de obtener los resultados de la búsqueda, tu app puede leerlos
y realizar cualquier procesamiento, análisis o agregación que necesites.
Ten en cuenta que, si tienes una gran cantidad de resultados de la búsqueda, es posible que no sea posible obtener la última página de resultados de la búsqueda (y el total de la búsqueda precisa) en un tiempo práctico.
Flujo de trabajo
Este es un ejemplo de flujo de trabajo para esta solución:
La app llama al método
fhir.search
, que muestra la primera página de los resultados de la búsqueda. La respuesta incluye una URL de paginación (Bundle.link.url
) si hay más resultados que mostrar.Si hay más resultados para mostrar, la app llama a la URL de paginación del paso anterior para obtener la siguiente página de resultados de la búsqueda.
La app repite el paso anterior hasta que no haya más resultados para mostrar o se alcance algún otro límite predefinido. Si llegas a la última página de resultados de la búsqueda, el total de la búsqueda es preciso.
La app procesa los resultados de la búsqueda.
Según tu caso de uso, la app puede realizar cualquiera de las siguientes acciones:
- Espera a que se reciban todos los resultados de la búsqueda antes de procesar los datos.
- Procesa los datos a medida que se reciben con cada llamada sucesiva a
fhir.search
. - Establece algún tipo de límite, como la cantidad de coincidencias que se muestran o el tiempo transcurrido. Cuando se alcanza el límite, puedes procesar los datos, no procesarlos o realizar alguna otra acción.
Opciones de diseño
Estas son algunas opciones de diseño que podrían disminuir la latencia de la búsqueda:
Establece un tamaño de página grande. Usa el parámetro
_count
para establecer un tamaño de página grande, de 500 a 1,000, según tu caso de uso. El uso de un tamaño de página más grande aumenta la latencia de cada recuperación de página, pero podría acelerar el proceso general, ya que se requieren menos recuperaciones de páginas para obtener el conjunto completo de resultados de la búsqueda.Limita los resultados de la búsqueda. Si todo lo que necesitas es un total de búsqueda preciso (no necesitas mostrar contenido de recursos), configura el parámetro
_elements
del métodofhir.search
comoidentifier
. Esto podría disminuir la latencia de tu consulta de búsqueda, en comparación con solicitar la devolución de recursos FHIR completos. Para obtener más información, consulta Limita los campos que se muestran en los resultados de la búsqueda.
Casos de uso que requieren la carga previa y el almacenamiento en caché
Es posible que necesites funciones más allá de lo que es posible con el mecanismo simple de llamar de forma sucesiva al método fhir.search
con URLs de paginación. Una posibilidad es crear una capa de almacenamiento en caché entre tu app y la tienda de FHIR que mantenga el estado de la sesión mientras se precargan y almacenan en caché los resultados de la búsqueda.
La app puede agrupar los resultados de la búsqueda en "páginas de apps" pequeñas de 10 o 20 coincidencias. Luego, la app puede entregar rápidamente estas páginas pequeñas al usuario de una manera directa y no secuencial, según las selecciones del usuario. Consulta Cómo navegar a una página cercana para ver un ejemplo de este tipo de flujo de trabajo.
Cómo navegar a una página cercana
Puedes crear una solución de baja latencia que permita a un usuario recorrer una gran cantidad de resultados de la búsqueda hasta que encuentre la coincidencia que busca. Puede escalar a una cantidad prácticamente ilimitada de coincidencias sin aumentar la latencia y con un aumento relativamente pequeño en el consumo de recursos. Un usuario puede navegar directamente a una página de resultados de la búsqueda, hasta una cantidad predeterminada de páginas hacia adelante o hacia atrás desde la página actual. Puedes proporcionar un total estimado de búsquedas con cada página de resultados. A modo de referencia, este diseño es similar al de la Búsqueda de Google.
Flujo de trabajo
En la Figura 1, se muestra un flujo de trabajo de ejemplo para esta solución. Con este flujo de trabajo, cada vez que el usuario selecciona una página de resultados para ver, la app proporciona vínculos a páginas cercanas. En este caso, la app proporciona vínculos a páginas hasta cinco hacia atrás de la página seleccionada y hasta cuatro hacia adelante de la página seleccionada. Para que las cuatro páginas de paginación hacia adelante estén disponibles para su visualización, la app precarga 40 coincidencias adicionales cuando el usuario selecciona una página de resultados.
Figura 1. La app agrupa los resultados de la búsqueda en "páginas de la app" que se almacenan en caché y se ponen a disposición del usuario.
En la Figura 1, se ilustran estos pasos:
El usuario ingresa una búsqueda en el frontend de la app, lo que inicia las siguientes acciones:
La app llama al método
fhir.search
para recuperar previamente la primera página de los resultados de la búsqueda.El parámetro
_count
se establece en 100 para mantener el tamaño de la página de la respuesta relativamente pequeño, lo que genera tiempos de respuesta relativamente rápidos. La respuesta incluye una URL de paginación (Bundle.link.url
) si hay más resultados que mostrar. La respuesta también incluye el total de búsquedas (Bundle.total
). El total de búsquedas es una estimación si hay más resultados que mostrar. Para obtener más información, consulta Paginación y ordenamiento.La app envía la respuesta a la capa de almacenamiento en caché.
En la capa de almacenamiento en caché, la app agrupa las 100 coincidencias de la respuesta en 10 páginas de la app de 10 coincidencias cada una. Una página de app es una pequeña agrupación de coincidencias que la app puede mostrarle al usuario.
La app le muestra al usuario la página 1. La página 1 de la app incluye vínculos a las páginas 2 a 10 de la app y el total estimado de búsquedas.
El usuario hace clic en un vínculo a una página diferente de la app (página 10 de la app en este ejemplo) e inicia las siguientes acciones:
La app llama al método
fhir.search
, con la URL de paginación que se mostró con la carga previa anterior, para cargar previamente la siguiente página de resultados de la búsqueda.El parámetro
_count
se establece en 40 para recuperar previamente las próximas 40 coincidencias de la búsqueda del usuario. Las 40 coincidencias corresponden a las siguientes cuatro páginas de la app que la app pone a disposición del usuario.La app envía la respuesta a la capa de almacenamiento en caché.
En la capa de almacenamiento en caché, la app agrupa las 40 coincidencias de la respuesta en cuatro páginas de la app de 10 coincidencias cada una.
La app muestra la página 10 al usuario. La página 10 de la app incluye vínculos a las páginas 5 a 9 (las cinco páginas anteriores a la página 10) y a las páginas 11 a 14 (las cuatro páginas posteriores a la página 10). La página 10 de la app también incluye el total estimado de búsquedas.
Esto puede continuar mientras el usuario desee seguir haciendo clic en los vínculos a las páginas de la app. Ten en cuenta que, si el usuario navega hacia atrás desde la página de la app actual y ya tienes todas las páginas de la app cercanas almacenadas en caché, puedes optar por no realizar una nueva carga previa, según tu caso de uso.
Esta solución es rápida y eficiente por los siguientes motivos:
- Los precargamientos pequeños y las páginas de la app aún más pequeñas se procesan rápidamente.
- Los resultados de la búsqueda almacenados en caché reducen la necesidad de realizar varias llamadas para obtener los mismos resultados.
- El mecanismo sigue siendo rápido sin importar qué tan alta sea la escala de la cantidad de resultados de la búsqueda.
Opciones de diseño
Estas son algunas opciones de diseño que debes considerar, según tu caso de uso:
Tamaño de la página de la app. Las páginas de tu app pueden contener más de 10 coincidencias si se ajustan a tu caso de uso. Ten en cuenta que las páginas más pequeñas se cargan más rápido y que puede ser difícil para un usuario administrar demasiados vínculos en una página.
Cantidad de vínculos a la página de la aplicación. En el flujo de trabajo que se sugiere aquí, cada página de la app muestra nueve vínculos a otras páginas de la app: cinco vínculos a las páginas de la app directamente hacia atrás desde la página actual y cuatro vínculos a las páginas directamente hacia adelante desde la página actual. Puedes ajustar estos números para que se adapten a tu caso de uso.
Prácticas recomendadas
Usa la capa de almacenamiento en caché solo cuando sea necesario. Si configuras una capa de almacenamiento en caché, úsala solo cuando tu caso de uso lo requiera. Las búsquedas que no requieren la capa de almacenamiento en caché deben omitirla.
Reduce el tamaño de la caché. Para conservar recursos, puedes reducir el tamaño de la caché purgando los resultados de la búsqueda anteriores y, al mismo tiempo, conservando las URLs de página que usaste para obtener los resultados. Luego, puedes reconstruir la caché según sea necesario llamando a las URLs de la página. Ten en cuenta que los resultados de varias llamadas a la misma URL de paginación pueden cambiar con el tiempo, ya que los recursos de la tienda de FHIR se crean, actualizan y borran en segundo plano. Si debes borrar la caché, cómo hacerlo y con qué frecuencia, son decisiones de diseño que dependen de tu caso de uso.
Borra la caché de una búsqueda determinada. Para conservar recursos, puedes quitar por completo de la caché los resultados de las búsquedas inactivas. Considera quitar primero las búsquedas que llevan más tiempo inactivas. Ten en cuenta que, si una búsqueda purgada vuelve a estar activa, es posible que se genere un estado de error que obligue a la capa de almacenamiento en caché a reiniciar la búsqueda.
Navegar a cualquier página
Si deseas que un usuario pueda navegar a cualquier página de los resultados de la búsqueda, no solo a las páginas cercanas a la página actual, puedes usar una capa de almacenamiento en caché similar a la que se describe en Cómo navegar a una página cercana. Sin embargo, para permitir que un usuario navegue a cualquier página de la app de los resultados de la búsqueda, deberás recuperar previamente y almacenar en caché todos los resultados de la búsqueda. Esto es posible con una cantidad relativamente pequeña de resultados de la búsqueda. Con una gran cantidad de resultados de la búsqueda, puede ser poco práctico o imposible recuperarlos todos de antemano. Incluso con una cantidad modesta de resultados de la búsqueda, el tiempo que se tarda en obtenerlos de antemano puede ser mayor de lo razonable esperar que un usuario espere.
Flujo de trabajo
Configura un flujo de trabajo similar al de Navegar a una página cercana, con esta diferencia clave: la app continúa realizando la precarga de los resultados de la búsqueda en segundo plano hasta que se muestran todas las coincidencias o se alcanza algún otro límite predefinido.
Este es un ejemplo de flujo de trabajo para esta solución:
La app llama al método
fhir.search
para recuperar previamente la primera página de resultados de la búsqueda de la búsqueda del usuario. La respuesta incluye una URL de paginación (Bundle.link.url
) si hay más resultados para mostrar. La respuesta también incluye el total de la búsqueda (Bundle.total
). Esta es una estimación si hay más resultados que mostrar.La app agrupa las coincidencias de la respuesta en páginas de la app de 20 coincidencias cada una y las almacena en la caché. Una página de la app es una pequeña agrupación de coincidencias que la app puede mostrarle al usuario.
La app muestra la primera página al usuario. La página de la app incluye vínculos a las páginas de la app almacenadas en caché y el total estimado de búsquedas.
Si hay más resultados para mostrar, la app hace lo siguiente:
- Llama a la URL de paginación que se muestra desde la carga previa anterior para obtener la siguiente página de resultados de la búsqueda.
- Agrupa las coincidencias de la respuesta en páginas de apps de 20 coincidencias cada una y las almacena en la caché.
- Actualiza la página de la app que el usuario está viendo actualmente con vínculos nuevos a las páginas de la app que se recuperaron previamente y se almacenaron en caché.
La app repite el paso anterior hasta que no haya más resultados para mostrar o se alcance algún otro límite predefinido. Se muestra un total de búsqueda preciso con la última página de resultados de la búsqueda.
Mientras la app realiza la precarga y almacena en caché las coincidencias en segundo plano, el usuario puede seguir haciendo clic en los vínculos a las páginas almacenadas en caché.
Opciones de diseño
Estas son algunas opciones de diseño que debes considerar, según tu caso de uso:
Tamaño de la página de la app. Las páginas de tu app pueden contener más o menos de 20 coincidencias si se ajustan a tu caso de uso. Ten en cuenta que las páginas más pequeñas se cargan más rápido y que puede ser difícil para un usuario administrar demasiados vínculos en una página.
Actualiza el total de búsquedas. Mientras tu app precarga y almacena en caché los resultados de la búsqueda en segundo plano, puedes mostrarle al usuario totales de búsqueda más precisos de forma progresiva. Para ello, configura tu app para que haga lo siguiente:
En un intervalo establecido, obtén el total de búsquedas (la propiedad
Bundle.total
) de la precarga más reciente en la capa de almacenamiento en caché. Esta es la mejor estimación actual del total de búsquedas. Muestra el total de la búsqueda al usuario y dile que es una estimación. Determina la frecuencia de esta actualización según tu caso de uso.Reconocer cuándo el total de búsquedas de la capa de almacenamiento en caché es preciso Es decir, el total de búsquedas corresponde a la última página de los resultados de la búsqueda. Cuando se llega a la última página de resultados de la búsqueda, la app muestra el total de la búsqueda y le indica al usuario que es preciso. Luego, la app deja de obtener totales de búsqueda de la capa de almacenamiento en caché.
Ten en cuenta que, con una gran cantidad de coincidencias, es posible que la precarga en segundo plano y el almacenamiento en caché no lleguen a la última página de los resultados de la búsqueda (y el total de la búsqueda precisa) antes de que el usuario complete su sesión de búsqueda.
Prácticas recomendadas
Eliminar los recursos duplicados Si usas los parámetros
_include
y_revinclude
cuando se precargan y almacenan en caché los resultados de la búsqueda, te recomendamos que dedupliques los recursos incluidos en la caché después de cada precarga. Esto ayudará a ahorrar memoria, ya que se reducirá el tamaño de la caché. Cuando agrupas coincidencias en páginas de aplicaciones, agrega los recursos incluidos adecuados a cada página de aplicación. Para obtener más información, consulta Cómo incluir recursos adicionales en los resultados de la búsqueda.Establece un límite en la carga previa y el almacenamiento en caché. Con una gran cantidad de resultados de la búsqueda, puede ser poco práctico o imposible recuperarlos todos de antemano. Te recomendamos que establezcas un límite para la cantidad de resultados de la búsqueda que se deben recuperar previamente. Esto mantiene tu caché en un tamaño manejable y ayuda a ahorrar memoria. Por ejemplo, podrías limitar el tamaño de la caché a 10,000 o 20,000 coincidencias. Como alternativa, puedes limitar la cantidad de páginas para la carga previa o establecer un límite de tiempo después del cual se detenga la carga previa. El tipo de límite que impones y la forma en que lo impones son decisiones de diseño que dependen de tu caso de uso. Si se alcanza el límite antes de que se muestren todos los resultados de la búsqueda, considera indicarle esto al usuario, incluido que el total de la búsqueda sigue siendo una estimación.
Almacenamiento en caché del frontend
El frontend de la aplicación, como un navegador web o una app para dispositivos móviles, puede proporcionar un almacenamiento en caché de los resultados de la búsqueda como alternativa a la introducción de una capa de almacenamiento en caché en la arquitectura. Este enfoque puede proporcionar navegación a la página anterior o a cualquier página del historial de navegación aprovechando las llamadas AJAX y almacenando los resultados de la búsqueda o las URLs de paginación. Estas son algunas de las ventajas de este enfoque:
- Puede requerir menos recursos que una capa de almacenamiento en caché.
- Es más escalable, ya que distribuye el trabajo de almacenamiento en caché entre muchos clientes.
- Es más fácil determinar cuándo ya no se necesitan los recursos almacenados en caché, por ejemplo, cuando el usuario cierra una pestaña o sale de la interfaz de búsqueda.
Prácticas recomendadas generales
Estas son algunas prácticas recomendadas que se aplican a todas las soluciones de este documento.
Planifica que las páginas sean más pequeñas que el valor de _count. En algunas circunstancias, una búsqueda puede mostrar páginas que contienen menos coincidencias que el valor de
_count
que especificaste. Por ejemplo, esto podría ocurrir si especificas un tamaño de página particularmente grande. Si la búsqueda muestra una página que es más pequeña que el valor de_count
y tu app usa una capa de almacenamiento en caché, es posible que debas decidir si (1) mostrar menos resultados de lo esperado en una página de la app o (2) recuperar algunos resultados más para obtener suficientes para una página de la app completa. Para obtener más información, consulta Paginación y ordenamiento.Vuelve a intentar los errores de solicitud HTTP que se pueden volver a intentar. Tu app debe esperar errores de solicitud HTTP que se puedan volver a intentar, como
429
o500
, y volver a intentarlo después de recibirlos.
Evalúa tus casos de uso
La implementación de funciones como navegar a cualquier página, obtener totales de búsqueda precisos y actualizar los totales estimados aumenta la complejidad y los costos de desarrollo de tu app. Estas funciones también pueden aumentar la latencia y los costos monetarios por el uso de recursos de Google Cloud. Te recomendamos que evalúes cuidadosamente tus casos de uso para asegurarte de que el valor de estas funciones justifique los costos. Estos son algunos aspectos que debes tener en cuenta:
Navegar a cualquier página Por lo general, un usuario no necesita navegar a una página específica, sino a muchas páginas desde la página actual. En la mayoría de los casos, navegar a una página cercana es adecuado.
Totales de búsqueda precisos. Los totales de búsqueda pueden cambiar a medida que se crean, actualizan y borran los recursos del almacén de FHIR. Por este motivo, un total de búsqueda exacto es preciso en el momento en que se muestra (con la última página de resultados de la búsqueda), pero es posible que no lo siga siendo con el tiempo. Por lo tanto, los totales de búsqueda precisos pueden tener un valor limitado para tu app, según tu caso de uso.