La implementación de la búsqueda de FHIR de la API Cloud Healthcare es altamente escalable y eficiente, y sigue las directrices y limitaciones de REST y de la especificación FHIR. Para conseguirlo, la búsqueda de FHIR tiene las siguientes propiedades:
El total de la búsqueda es una estimación hasta que se devuelve la última página. Los resultados de búsqueda devueltos por el método
fhir.search
incluyen el total de la búsqueda (la propiedadBundle.total
), que es el número total de coincidencias en la búsqueda. El total de búsquedas es una estimación hasta que se devuelve la última página de resultados de búsqueda. El total de la búsqueda devuelto con la última página de resultados es la suma exacta de todas las coincidencias de la búsqueda.Los resultados de búsqueda ofrecen una paginación secuencial hacia delante. Cuando hay más resultados de búsqueda que devolver, la respuesta incluye una URL de paginación (
Bundle.link.url
) para obtener la página de resultados siguiente.
Casos prácticos básicos
La búsqueda de FHIR ofrece soluciones para los siguientes casos prácticos:
- Navega de forma secuencial. Un usuario navega hacia adelante de forma secuencial por un número limitado de páginas de resultados de búsqueda. Con cada página se devuelve un total de búsquedas estimado.
- Procesar un conjunto de resultados de búsqueda Una aplicación obtiene un conjunto de resultados de búsqueda, los lee y procesa los datos.
En las siguientes secciones se indican posibles soluciones para estos casos prácticos.
Desplazarse secuencialmente
Puedes crear una aplicación de baja latencia que permita a un usuario desplazarse secuencialmente por las páginas de resultados hasta que encuentre la coincidencia que busca. Esta solución es viable si el número de coincidencias es lo suficientemente pequeño como para que el usuario pueda encontrar la que busca navegando por las páginas sin saltarse resultados. Si tu caso práctico requiere que los usuarios se desplacen varias páginas hacia delante a la vez o que se desplacen hacia atrás, consulta Desplazarse a una página cercana.
Esta solución no puede proporcionar un total de búsqueda preciso hasta que se devuelva la última página de resultados. Sin embargo, puede proporcionar un total de búsqueda aproximado en cada página de resultados. Aunque un total de búsquedas preciso podría ser un requisito para un proceso en segundo plano, un total de búsquedas aproximado suele ser suficiente para un usuario humano.
Flujo de trabajo
A continuación, se muestra un ejemplo de flujo de trabajo para esta solución:
Una aplicación llama al método
fhir.search
, que devuelve la primera página de resultados de búsqueda. La respuesta incluye una URL de paginación (Bundle.link.url
) si hay más resultados que devolver. La respuesta también incluye el total de la búsqueda (Bundle.total
). Si hay más resultados que devolver 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 ordenación.La aplicación muestra la página de resultados de búsqueda, un enlace a la página siguiente de resultados (si la hay) y el total de búsquedas.
Si el usuario quiere ver la página siguiente de resultados, hace clic en el enlace, 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 que devolver. La respuesta también incluye el total de búsquedas. Se trata de una estimación actualizada si hay más resultados que devolver.
La aplicación muestra la nueva página de resultados de búsqueda, un enlace a la página siguiente de resultados (si la hay) y el total de resultados de la búsqueda.
Los dos pasos anteriores se repiten hasta que el usuario deja de buscar o se devuelve la última página de resultados.
Práctica recomendada
Elige un tamaño de página que sea adecuado para que una persona pueda leerlo sin dificultad. En función de tu caso práctico, puede que haya entre 10 y 20 coincidencias por página. Las páginas más pequeñas se cargan más rápido y, si hay demasiados enlaces en una página, puede resultar difícil de gestionar para los usuarios. Puedes controlar el tamaño de la página con el parámetro _count
.
Procesar un conjunto de resultados de búsqueda
Puedes obtener un conjunto de resultados de búsqueda haciendo llamadas sucesivas al método fhir.search
con la URL de paginación. Si el número de resultados de búsqueda es lo suficientemente pequeño, puedes obtener un conjunto completo de resultados continuando hasta que no haya más páginas que devolver. En la última página de resultados se incluye un total de búsqueda preciso. Después de obtener los resultados de búsqueda, tu aplicación puede leerlos y realizar el procesamiento, el análisis o la agregación que necesites.
Ten en cuenta que, si tienes un número muy elevado de resultados de búsqueda, es posible que no puedas obtener la última página de resultados de búsqueda (y el total de búsquedas exacto) en un tiempo razonable.
Flujo de trabajo
A continuación, se muestra un ejemplo de flujo de trabajo para esta solución:
La aplicación llama al método
fhir.search
, que devuelve la primera página de resultados de búsqueda. La respuesta incluye una URL de paginación (Bundle.link.url
) si hay más resultados que devolver.Si hay más resultados que devolver, la aplicación llama a la URL de paginación del paso anterior para obtener la siguiente página de resultados de búsqueda.
La aplicación repite el paso anterior hasta que no haya más resultados que devolver o se alcance otro límite predefinido. Si llegas a la última página de resultados de búsqueda, el total de la búsqueda será preciso.
La aplicación procesa los resultados de búsqueda.
En función de tu caso práctico, tu aplicación puede hacer lo siguiente:
- Espera a recibir todos los resultados de búsqueda antes de procesar los datos.
- Procesa los datos a medida que se reciben con cada llamada sucesiva a
fhir.search
. - Define algún tipo de límite, como el número de coincidencias devueltas o el tiempo transcurrido. Cuando se alcance el límite, podrá procesar los datos, no procesarlos o realizar otra acción.
Opciones de diseño
Estas son algunas opciones de diseño que pueden reducir la latencia de búsqueda:
Define un tamaño de página grande. Usa el parámetro
_count
para definir un tamaño de página grande, quizás de 500 a 1000, en función de tu caso práctico. Si se usa un tamaño de página mayor, aumenta la latencia de cada obtención de página, pero puede acelerar el proceso general, ya que se necesitan menos obtenciones de páginas para obtener todo el conjunto de resultados de búsqueda.Limita los resultados de búsqueda. Si solo necesitas un total de búsqueda preciso (no necesitas devolver contenido de recursos), asigna el valor
identifier
al parámetro_elements
del métodofhir.search
. Esto puede reducir la latencia de tu consulta de búsqueda en comparación con la solicitud de devolución de recursos FHIR completos. Para obtener más información, consulta Limitar los campos devueltos en los resultados de búsqueda.
Casos prácticos que requieren la precarga y el almacenamiento en caché
Es posible que necesites funciones que vayan más allá de lo que se puede hacer con el mecanismo sencillo de llamar sucesivamente al método fhir.search
mediante URLs de paginación. Una opción es crear una capa de caché entre tu aplicación y el almacén de FHIR que mantenga el estado de la sesión mientras prefiere y almacena en caché los resultados de búsqueda.
La aplicación puede agrupar los resultados de búsqueda en pequeñas "páginas de aplicaciones" de 10 o 20 coincidencias. De esta forma, la aplicación puede servir rápidamente estas pequeñas páginas de la aplicación al usuario de forma directa y no secuencial, en función de las selecciones del usuario. Consulta Ir a una página cercana para ver un ejemplo de este tipo de flujo de trabajo.
Desplazarse a una página cercana
Puedes crear una solución de baja latencia que permita a los usuarios consultar un gran número de resultados de búsqueda hasta que encuentren la coincidencia que buscan. Puede ampliarse a un número prácticamente ilimitado de coincidencias, manteniendo una latencia baja y con un aumento relativamente pequeño del consumo de recursos. Un usuario puede ir directamente a una página de resultados de búsqueda, hasta un número predeterminado de páginas hacia delante o hacia atrás desde la página actual. Puedes proporcionar un total de búsquedas estimado con cada página de resultados. Este diseño es similar al de la Búsqueda de Google.
Flujo de trabajo
En la imagen 1 se muestra un ejemplo de flujo de trabajo de esta solución. Con este flujo de trabajo, cada vez que el usuario selecciona una página de resultados para verla, la aplicación proporciona enlaces a páginas cercanas. En este caso, la aplicación proporciona enlaces a páginas que están hasta cinco páginas antes de la página seleccionada y hasta cuatro páginas después de la página seleccionada. Para que las cuatro páginas siguientes estén disponibles, la aplicación precarga 40 resultados adicionales cuando el usuario selecciona una página de resultados.
Imagen 1. La aplicación agrupa los resultados de búsqueda en "páginas de aplicaciones" que se almacenan en caché y se ponen a disposición del usuario.
En la figura 1 se muestran estos pasos:
El usuario introduce una consulta de búsqueda en el frontend de la aplicación, lo que inicia las siguientes acciones:
La aplicación llama al método
fhir.search
para prefetch la primera página de resultados de búsqueda.El parámetro
_count
se define en 100 para que el tamaño de la página de la respuesta sea relativamente pequeño, lo que da lugar a tiempos de respuesta relativamente rápidos. La respuesta incluye una URL de paginación (Bundle.link.url
) si hay más resultados que devolver. La respuesta también incluye el total de la búsqueda (Bundle.total
). El total de la búsqueda es una estimación si hay más resultados que devolver. Para obtener más información, consulta Paginación y ordenación.La aplicación envía la respuesta a la capa de caché.
En la capa de caché, la aplicación agrupa las 100 coincidencias de la respuesta en 10 páginas de la aplicación con 10 coincidencias cada una. Una página de aplicación es un pequeño grupo de coincidencias que la aplicación puede mostrar al usuario.
La aplicación muestra la página 1 de la aplicación al usuario. La página 1 de la aplicación incluye enlaces a las páginas 2-10 de la aplicación y el total de búsquedas estimado.
El usuario hace clic en un enlace a otra página de la aplicación (la página 10 en este ejemplo), lo que inicia las siguientes acciones:
La aplicación llama al método
fhir.search
y usa la URL de paginación que se devolvió con la prefetched anterior para prefetch la siguiente página de resultados de búsqueda.El parámetro
_count
se define en 40 para prefetch los 40 resultados siguientes de la consulta de búsqueda del usuario. Las 40 coincidencias corresponden a las cuatro páginas de la aplicación siguientes que la aplicación pone a disposición del usuario.La aplicación envía la respuesta a la capa de caché.
En la capa de almacenamiento en caché, la aplicación agrupa las 40 coincidencias de la respuesta en cuatro páginas de aplicaciones de 10 coincidencias cada una.
La aplicación muestra la página 10 al usuario. La página de la aplicación 10 incluye enlaces a las páginas de la aplicación 5-9 (las cinco páginas de la aplicación anteriores a la página de la aplicación 10) y enlaces a las páginas de la aplicación 11-14 (las cuatro páginas de la aplicación posteriores a la página de la aplicación 10). La página 10 de la aplicación también incluye el total de búsquedas estimado.
Esto puede continuar mientras el usuario quiera seguir haciendo clic en enlaces a páginas de la aplicación. Ten en cuenta que, si el usuario vuelve a la página de la aplicación actual y ya tienes en caché todas las páginas de aplicaciones cercanas, puedes optar por no hacer una nueva prefetched, en función de tu caso de uso.
Esta solución es rápida y eficaz por los siguientes motivos:
- Las prefetchs pequeñas y las páginas de aplicaciones aún más pequeñas se procesan rápidamente.
- Los resultados de búsqueda almacenados en caché reducen la necesidad de hacer varias llamadas para obtener los mismos resultados.
- El mecanismo sigue siendo rápido independientemente de la cantidad de resultados de búsqueda.
Opciones de diseño
A continuación, te indicamos algunas opciones de diseño que puedes tener en cuenta, en función de tu caso práctico:
Tamaño de la página de la aplicación. Las páginas de tu aplicación pueden contener más de 10 coincidencias si se ajustan a tu caso práctico. Ten en cuenta que las páginas más pequeñas se cargan más rápido y que demasiados enlaces en una página pueden dificultar la gestión de los usuarios.
Número de enlaces a la página de la aplicación. En el flujo de trabajo que se sugiere aquí, cada página de aplicación devuelve nueve enlaces a otras páginas de aplicación: cinco enlaces a las páginas de aplicación directamente anteriores a la página de aplicación actual y cuatro enlaces a las páginas directamente posteriores a la página de aplicación actual. Puedes ajustar estos números según tu caso práctico.
Prácticas recomendadas
Usa la capa de caché solo cuando sea necesario. Si configuras una capa de caché, úsala solo cuando sea necesario. Las búsquedas que no requieren la capa de caché deben omitirla.
Reduce el tamaño de la caché. Para ahorrar recursos, puedes reducir el tamaño de la caché eliminando los resultados de búsqueda antiguos y conservando las URLs de las páginas que usaste para obtenerlos. Después, puede reconstruir la caché según sea necesario llamando a las URLs de las páginas. Tenga en cuenta que los resultados de varias llamadas a la misma URL de paginación pueden cambiar con el tiempo, ya que los recursos del almacén de FHIR se crean, actualizan y eliminan en segundo plano. Si quieres purgar la caché, cómo hacerlo y con qué frecuencia son decisiones de diseño que dependen de tu caso práctico.
Purga la caché de una búsqueda concreta. Para ahorrar recursos, puedes eliminar por completo de la caché los resultados de las búsquedas inactivas. Te recomendamos que elimines primero las búsquedas que lleven más tiempo inactivas. Ten en cuenta que, si una búsqueda purgada vuelve a estar activa, puede provocar un error que fuerce a la capa de caché a reiniciar la búsqueda.
Ir a cualquier página
Si quieres que un usuario pueda ir a cualquier página de los resultados de búsqueda, no solo a las páginas cercanas a la página actual, puedes usar una capa de caché similar a la que se describe en Ir a una página cercana. Sin embargo, para permitir que un usuario vaya a cualquier página de aplicación de los resultados de búsqueda, deberá precargar y almacenar en caché todos los resultados de búsqueda. Esto es posible si el número de resultados de búsqueda es relativamente pequeño. Si hay un número muy elevado de resultados de búsqueda, puede ser poco práctico o imposible prefetcharlos todos. Incluso con un número reducido de resultados de búsqueda, el tiempo que se tarda en precargarlos puede ser mayor de lo que es razonable esperar que espere un usuario.
Flujo de trabajo
Configura un flujo de trabajo similar a Ir a una página cercana, con esta diferencia clave: la aplicación sigue precargando resultados de búsqueda en segundo plano hasta que se devuelvan todas las coincidencias o se alcance otro límite predefinido.
A continuación, se muestra un ejemplo de flujo de trabajo para esta solución:
La aplicación llama al método
fhir.search
para prefetch la primera página de resultados de búsqueda de la consulta de búsqueda del usuario. La respuesta incluye una URL de paginación (Bundle.link.url
) si hay más resultados que devolver. La respuesta también incluye el total de la búsqueda (Bundle.total
). Se trata de una estimación si hay más resultados que devolver.La aplicación agrupa las coincidencias de la respuesta en páginas de la aplicación de 20 coincidencias cada una y las almacena en la caché. Una página de aplicación es un pequeño grupo de coincidencias que la aplicación puede mostrar al usuario.
La aplicación muestra al usuario la primera página de la aplicación. La página de la aplicación incluye enlaces a las páginas de la aplicación almacenadas en caché y el total de búsquedas estimado.
Si hay más resultados que devolver, la aplicación hace lo siguiente:
- Llama a la URL de paginación devuelta por la prefetched anterior para obtener la siguiente página de resultados de búsqueda.
- Agrupa las coincidencias de la respuesta en páginas de aplicaciones de 20 coincidencias cada una y las almacena en la caché.
- Actualiza la página de la aplicación que está viendo el usuario con enlaces nuevos a las páginas de la aplicación que se han prefetch y almacenado en caché recientemente.
La aplicación repite el paso anterior hasta que no haya más resultados que devolver o se alcance otro límite predefinido. El total de búsquedas preciso se devuelve con la última página de resultados de búsqueda.
Mientras la aplicación prefetch y almacena en caché las coincidencias en segundo plano, el usuario puede seguir haciendo clic en los enlaces a las páginas almacenadas en caché.
Opciones de diseño
A continuación, te indicamos algunas opciones de diseño que puedes tener en cuenta, en función de tu caso práctico:
Tamaño de la página de la aplicación. Las páginas de tu aplicación pueden contener más o menos de 20 coincidencias si se ajustan a tu caso práctico. Ten en cuenta que las páginas más pequeñas se cargan más rápido y que, si una página tiene demasiados enlaces, puede resultar difícil de gestionar para los usuarios.
Actualiza el total de la búsqueda. Mientras tu aplicación prefiere y almacena en caché los resultados de búsqueda en segundo plano, puedes mostrar al usuario totales de búsqueda cada vez más precisos. Para ello, configura tu aplicación para que haga lo siguiente:
A intervalos definidos, obtiene el total de búsquedas (la propiedad
Bundle.total
) de la prefetch más reciente de la capa de caché. Esta es la mejor estimación actual del total de búsquedas. Muestra el total de la búsqueda al usuario e indica que es una estimación. Determina la frecuencia de esta actualización en función de tu caso práctico.Reconocer cuándo es preciso el total de búsquedas de la capa de caché. Es decir, el total de la búsqueda corresponde a la última página de resultados de búsqueda. Cuando se llega a la última página de resultados de búsqueda, la aplicación muestra el total de la búsqueda e indica al usuario que es correcto. Después, la aplicación deja de recibir totales de búsquedas de la capa de caché.
Ten en cuenta que, si hay un gran número de coincidencias, la precarga y el almacenamiento en caché en segundo plano podrían no llegar a la última página de resultados de búsqueda (y al total de búsquedas preciso) antes de que el usuario complete su sesión de búsqueda.
Prácticas recomendadas
Elimina los recursos incluidos duplicados. Si usas los parámetros
_include
y_revinclude
al prefetch y almacenar en caché los resultados de búsqueda, te recomendamos que elimines los recursos duplicados incluidos en la caché después de cada prefetch. De esta forma, ahorrarás memoria al reducir el tamaño de la caché. Cuando agrupe las coincidencias en páginas de la aplicación, añada los recursos incluidos correspondientes a cada página de la aplicación. Para obtener más información, consulta el artículo Incluir recursos adicionales en los resultados de búsqueda.Define un límite para la precarga y el almacenamiento en caché. Si hay un número muy elevado de resultados de búsqueda, puede ser poco práctico o imposible prefetcharlos todos. Te recomendamos que definas un límite en el número de resultados de búsqueda que se van a prefetched. De esta forma, la caché tendrá un tamaño adecuado y se ahorrará memoria. Por ejemplo, puedes limitar el tamaño de la caché a 10.000 o 20.000 coincidencias. También puedes limitar el número de páginas que se van a precargar o establecer un límite de tiempo tras el cual se detendrá la precarga. El tipo de límite que impongas y la forma en que lo hagas son decisiones de diseño que dependen de tu caso práctico. Si se alcanza el límite antes de que se devuelvan todos los resultados de búsqueda, indica al usuario 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 aplicación móvil, puede proporcionar un almacenamiento en caché de los resultados de 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 mediante llamadas AJAX y el almacenamiento de resultados de búsqueda o 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 abandona la interfaz de búsqueda.
Prácticas recomendadas generales
A continuación, se indican 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 _count. En algunos casos, una búsqueda puede devolver páginas que contengan menos coincidencias que el valor
_count
que especifiques. Por ejemplo, esto puede ocurrir si especificas un tamaño de página especialmente grande. Si tu búsqueda devuelve una página que es más pequeña que el valor de_count
y tu aplicación usa una capa de caché, puede que tengas que decidir si quieres (1) mostrar menos resultados de lo esperado en una página de la aplicación o (2) obtener algunos resultados más para completar la página de la aplicación. Para obtener más información, consulta Paginación y ordenación.Reintenta los errores de solicitudes HTTP que se pueden reintentar. Tu aplicación debe esperar errores de solicitud HTTP reintentables, como
429
o500
, y volver a intentarlo después de recibirlos.
Evaluar tus casos prácticos
Implementar funciones como ir a cualquier página, obtener totales de búsqueda precisos y actualizar los totales estimados aumenta la complejidad y los costes de desarrollo de tu aplicación. Estas funciones también pueden aumentar la latencia y los costes económicos del uso de recursos de Google Cloud. Te recomendamos que evalúes detenidamente tus casos prácticos para asegurarte de que el valor de estas funciones justifica los costes. Ten en cuenta lo siguiente:
Ir a cualquier página. Por lo general, un usuario no necesita ir a una página específica, sino a muchas páginas desde la página actual. En la mayoría de los casos, desplazarse a una página cercana es suficiente.
Totales de búsqueda precisos. Los totales de búsqueda pueden cambiar a medida que se crean, actualizan y eliminan recursos en el almacén FHIR. Por este motivo, el total de búsquedas es preciso en el momento en que se devuelve (con la última página de resultados de búsqueda), pero puede que no siga siendo preciso con el tiempo. Por lo tanto, los totales de búsqueda precisos pueden tener un valor limitado para tu aplicación, en función de tu caso práctico.