A implementação da pesquisa FHIR da API Cloud Healthcare é altamente escalonável e eficiente, seguindo as diretrizes e limitações do REST e da especificação FHIR. Para ajudar a fazer isso, a pesquisa FHIR tem as seguintes propriedades:
O total de pesquisas é uma estimativa até que a última página seja retornada. Os resultados de pesquisa retornados pelo método
fhir.search
incluem o total de pesquisa (a propriedadeBundle.total
), que é o número total de correspondências na pesquisa. O total de pesquisas é uma estimativa até que a última página de resultados seja retornada. O total da pesquisa retornado com a última página de resultados é uma soma precisa de todas as correspondências na pesquisa.Os resultados da pesquisa fornecem paginação sequencial e direta. Quando há mais resultados de pesquisa para retornar, a resposta inclui um URL de paginação (
Bundle.link.url
) para acessar a próxima página de resultados.
Casos de uso básicos
A pesquisa FHIR oferece soluções para os seguintes casos de uso:
- Navegue de forma sequencial. Um usuário navega sequencialmente por um número limitado de páginas de resultados da pesquisa. Um total estimado de pesquisas é retornado com cada página.
- Processar um conjunto de resultados da pesquisa. Um app recebe um conjunto de resultados de pesquisa, lê os resultados e processa os dados.
Consulte as seções a seguir para conferir possíveis soluções para esses casos de uso.
Navegar sequencialmente
É possível criar um aplicativo de baixa latência que permite que um usuário navegue sequencialmente pelas páginas de resultados até encontrar a correspondência que ele quer. Essa solução é viável se o número de correspondências for pequeno o suficiente para que o usuário possa encontrar a correspondência desejada navegando página por página sem pular resultados. Se o seu caso de uso exige que os usuários naveguem para frente em várias páginas ao mesmo tempo ou para trás, consulte Navegar até uma página próxima.
Essa solução não pode fornecer um total de pesquisa preciso até que a última página de resultados seja retornada. No entanto, ele pode fornecer um total aproximado de pesquisa com cada página de resultados. Embora um total de pesquisa preciso possa ser um requisito para um processo em segundo plano, um total de pesquisa aproximado geralmente é adequado para um usuário humano.
Fluxo de trabalho
Confira um exemplo de fluxo de trabalho para essa solução:
Um app chama o método
fhir.search
, que retorna a primeira página dos resultados da pesquisa. A resposta inclui um URL de paginação (Bundle.link.url
) se houver mais resultados para retornar. A resposta também inclui o total de pesquisas (Bundle.total
). Se houver mais resultados a serem retornados do que na resposta inicial, o total de pesquisas será apenas uma estimativa. Para mais informações, consulte Paginação e classificação.O app mostra a página de resultados da pesquisa, um link para a próxima página de resultados (se houver) e o total de pesquisas.
Se o usuário quiser ver a próxima página de resultados, ele clicará no link, o que resultará em uma chamada para o URL de paginação. A resposta inclui um novo URL de paginação se houver mais resultados para retornar. A resposta também inclui o total de pesquisas. Essa é uma estimativa atualizada se houver mais resultados a serem retornados.
O app mostra a nova página de resultados da pesquisa, um link para a próxima página de resultados (se houver) e o total de pesquisas.
As duas etapas anteriores são repetidas até que o usuário pare de pesquisar ou a última página de resultados seja retornada.
Prática recomendada
Escolha um tamanho de página adequado para que uma pessoa leia sem dificuldade. Dependendo
do seu caso de uso, isso pode ser de 10 a 20 correspondências por página. Páginas menores são carregadas
mais rápido, e muitos links em uma página podem ser difíceis de gerenciar para o usuário. Você
controla o tamanho da página com o parâmetro _count
.
Processar um conjunto de resultados de pesquisa
É possível receber um conjunto de resultados de pesquisa fazendo chamadas sucessivas para o
método fhir.search
usando o URL de paginação. Se o número de resultados da pesquisa
for pequeno, você poderá receber um conjunto completo de resultados continuando até que
não haja mais páginas para retornar. Um total de pesquisa preciso é incluído na última
página de resultados. Depois de receber os resultados da pesquisa, o app pode lê-los
e realizar qualquer processamento, análise ou agregação necessária.
Se você tiver um número muito grande de resultados da pesquisa, talvez não seja possível acessar a última página dos resultados da pesquisa (e o total de pesquisas exatas) em um período prático.
Fluxo de trabalho
Confira um exemplo de fluxo de trabalho para essa solução:
O app chama o método
fhir.search
, que retorna a primeira página dos resultados da pesquisa. A resposta inclui um URL de paginação (Bundle.link.url
) se houver mais resultados a serem retornados.Se houver mais resultados para retornar, o app vai chamar o URL de paginação da etapa anterior para acessar a próxima página de resultados da pesquisa.
O app repete a etapa anterior até que não haja mais resultados para retornar ou até que algum outro limite predefinido seja atingido. Se você chegar à última página de resultados da pesquisa, o total da pesquisa será preciso.
O app processa os resultados da pesquisa.
Dependendo do caso de uso, o app pode:
- Aguarde até que todos os resultados da pesquisa sejam recebidos antes de processar os dados.
- Processe os dados conforme eles são recebidos com cada chamada sucessiva para
fhir.search
. - Defina algum tipo de limite, como o número de correspondências retornadas ou o tempo decorrido. Quando o limite for alcançado, você poderá processar os dados, não processar os dados ou fazer outra ação.
Opções de design
Confira algumas opções de design que podem diminuir a latência da pesquisa:
Defina um tamanho de página grande. Use o parâmetro
_count
para definir um tamanho de página grande, talvez de 500 a 1.000, dependendo do seu caso de uso. Usar um tamanho de página maior aumenta a latência de cada busca de página, mas pode acelerar o processo geral, já que menos buscas de página são necessárias para receber todo o conjunto de resultados da pesquisa.Limitar os resultados da pesquisa. Se tudo o que você precisa é de um total de pesquisa preciso (não precisa retornar o conteúdo do recurso), defina o parâmetro
_elements
do métodofhir.search
comoidentifier
. Isso pode diminuir a latência da consulta de pesquisa, em comparação com a solicitação de retorno de recursos FHIR completos. Para mais informações, consulte Como limitar os campos retornados nos resultados da pesquisa.
Casos de uso que exigem pré-busca e armazenamento em cache
Talvez você precise de uma funcionalidade além do que é possível usando o mecanismo simples
de chamar o método fhir.search
sucessivamente usando URLs de paginação. Uma
possibilidade é criar uma camada de armazenamento em cache entre o app e a loja FHIR
que mantenha o estado da sessão enquanto faz a pré-busca e o armazenamento em cache dos resultados da pesquisa.
O app pode agrupar os resultados da pesquisa em pequenas "páginas de apps" de 10 ou 20
resultados. O app pode exibir essas pequenas páginas rapidamente para o
usuário de maneira direta e não sequencial, com base nas seleções do usuário. Consulte
Navegar até uma página próxima para conferir um exemplo desse
tipo de fluxo de trabalho.
Navegar até uma página próxima
É possível criar uma solução de baixa latência que permite que um usuário navegue por um grande número de resultados da pesquisa até encontrar a correspondência que procura. Ele pode ser dimensionado para um número praticamente ilimitado de correspondências, mantendo a latência baixa e gerando um aumento relativamente pequeno no consumo de recursos. Um usuário pode navegar diretamente para uma página de resultados da pesquisa, até um número predeterminado de páginas para frente ou para trás da página atual. Você pode fornecer um total de pesquisa estimado com cada página de resultados. Para referência, esse design é semelhante ao da Pesquisa Google.
Fluxo de trabalho
A Figura 1 mostra um exemplo de fluxo de trabalho para essa solução. Com esse fluxo de trabalho, sempre que o usuário seleciona uma página de resultados para visualizar, o app fornece links para páginas próximas. Nesse caso, o app fornece links para até cinco páginas anteriores à página selecionada e até quatro páginas posteriores à página selecionada. Para disponibilizar as quatro páginas de resultados para visualização, o app faz o pré-carregamento de 40 correspondências adicionais quando o usuário seleciona uma página de resultados.
Figura 1. O app agrupa os resultados da pesquisa em "páginas do app" que são armazenadas em cache e disponibilizadas para o usuário.
A Figura 1 ilustra essas etapas:
O usuário insere uma consulta de pesquisa no front-end do app, iniciando as seguintes ações:
O app chama o método
fhir.search
para fazer o pré-carregamento da primeira página de resultados da pesquisa.O parâmetro
_count
é definido como 100 para manter o tamanho da página da resposta relativamente pequeno, resultando em tempos de resposta relativamente rápidos. A resposta inclui um URL de paginação (Bundle.link.url
) se houver mais resultados a serem retornados. A resposta também inclui o total de pesquisas (Bundle.total
). O total de pesquisas é uma estimativa se houver mais resultados a serem retornados. Para mais informações, consulte Paginação e classificação.O app envia a resposta para a camada de armazenamento em cache.
Na camada de armazenamento em cache, o app agrupa as 100 correspondências da resposta em 10 páginas de 10 correspondências cada. Uma página de app é um pequeno grupo de correspondências que o app pode mostrar ao usuário.
O app mostra a página 1 do app para o usuário. A página 1 do app inclui links para as páginas 2 a 10 do app e o total estimado de pesquisas.
O usuário clica em um link para uma página diferente do app (página 10 do app neste exemplo), iniciando as seguintes ações:
O app chama o método
fhir.search
, usando o URL de paginação que foi retornado com o prefetch anterior, para pré-carregar a próxima página de resultados da pesquisa.O parâmetro
_count
é definido como 40 para pré-carregar as próximas 40 correspondências da consulta de pesquisa do usuário. As 40 correspondências são para as próximas quatro páginas que o app disponibiliza ao usuário.O app envia a resposta para a camada de armazenamento em cache.
Na camada de armazenamento em cache, o app agrupa as 40 correspondências da resposta em quatro páginas de 10 correspondências cada.
O app mostra a página 10 para o usuário. A página 10 do app inclui links para as páginas 5 a 9 do app (as cinco páginas anteriores à página 10) e links para as páginas 11 a 14 do app (as quatro páginas seguintes à página 10). A página 10 do app também inclui o total estimado de pesquisas.
Isso pode continuar enquanto o usuário quiser continuar clicando em links para páginas do app. Se o usuário navegar para trás da página atual do app e você já tiver todas as páginas do app próximas em cache, poderá optar por não fazer uma nova busca antecipada, dependendo do caso de uso.
Essa solução é rápida e eficiente pelas seguintes razões:
- Pequenas previsões e até mesmo páginas de apps menores são processadas rapidamente.
- Os resultados da pesquisa em cache reduzem a necessidade de fazer várias chamadas para os mesmos resultados.
- O mecanismo continua rápido, não importa o quanto o número de resultados de pesquisa aumenta.
Opções de design
Confira algumas opções de design a serem consideradas, dependendo do caso de uso:
Tamanho da página do app. As páginas do app podem conter mais de 10 correspondências se for adequado ao seu caso de uso. Lembre-se de que páginas menores carregam mais rápido e que muitos links em uma página podem ser difíceis de gerenciar para o usuário.
Número de links da página do app. No fluxo de trabalho sugerido aqui, cada página do app retorna nove links para outras páginas do app: cinco links para as páginas do app diretamente para trás da página atual e quatro links para as páginas diretamente para a frente da página atual. É possível ajustar esses números para atender ao seu caso de uso.
Práticas recomendadas
Use a camada de armazenamento em cache somente quando necessário. Se você configurar uma camada de armazenamento em cache, use-a somente quando o caso de uso exigir. As pesquisas que não exigem a camada de armazenamento em cache precisam ignorá-la.
Reduza o tamanho do cache. Para economizar recursos, reduza o tamanho do cache excluindo os resultados de pesquisa antigos, mantendo os URLs de página usados para gerar os resultados. Em seguida, é possível reconstruir o cache conforme necessário chamando os URLs da página. Os resultados de várias chamadas para o mesmo URL de paginação podem mudar com o tempo, já que os recursos na loja FHIR são criados, atualizados e excluídos em segundo plano. A decisão de limpar, como limpar e com que frequência limpar o cache são decisões de design que dependem do seu caso de uso.
Limpar o cache de uma pesquisa específica. Para economizar recursos, você pode remover completamente do cache os resultados de pesquisas inativas. Considere remover primeiro as pesquisas mais antigas. Se uma pesquisa excluída voltar a ficar ativa, isso pode causar um estado de erro que força a camada de armazenamento em cache a reiniciar a pesquisa.
Navegar até qualquer página
Se você quiser que um usuário possa navegar para qualquer página nos resultados da pesquisa, e não apenas as páginas próximas à página atual, use uma camada de armazenamento em cache semelhante à descrita em Navegar até uma página próxima. No entanto, para permitir que um usuário navegue até qualquer página de resultados da pesquisa do app, você precisa fazer o pré-carregamento e armazenar em cache todos os resultados da pesquisa. Isso é possível com um número relativamente pequeno de resultados de pesquisa. Com um número muito grande de resultados de pesquisa, pode ser impraticável ou impossível fazer o pré-carregamento de todos. Mesmo com um número modesto de resultados de pesquisa, o tempo necessário para o pré-carregamento pode ser maior do que o tempo razoável de espera do usuário.
Fluxo de trabalho
Configure um fluxo de trabalho semelhante a Navegar até uma página próxima, com esta diferença fundamental: o app continua fazendo previsões antecipadas dos resultados da pesquisa em segundo plano até que todas as correspondências sejam retornadas ou até que algum outro limite predefinido seja atingido.
Confira um exemplo de fluxo de trabalho para essa solução:
O app chama o método
fhir.search
para pré-carregar a primeira página de resultados da consulta de pesquisa do usuário. A resposta inclui um URL de paginação (Bundle.link.url
) se houver mais resultados para retornar. A resposta também inclui o total de pesquisas (Bundle.total
). Essa é uma estimativa se houver mais resultados a serem retornados.O app agrupa as correspondências da resposta em páginas de 20 correspondências e as armazena no cache. Uma página de app é um pequeno grupo de correspondências que o app pode mostrar ao usuário.
O app mostra a primeira página do app para o usuário. A página do app inclui links para as páginas em cache e o total estimado de pesquisas.
Se houver mais resultados, o app fará o seguinte:
- Chama o URL de paginação retornado do pré-carregamento anterior para acessar a próxima página de resultados da pesquisa.
- Agrupa as correspondências da resposta em páginas de app de 20 correspondências cada e as armazena no cache.
- Atualiza a página do app que o usuário está visualizando com novos links para as páginas do app pré-buscadas e armazenadas em cache.
O app repete a etapa anterior até que não haja mais resultados para retornar ou até que algum outro limite predefinido seja atingido. Um total de pesquisa preciso é retornado com a última página de resultados da pesquisa.
Enquanto o app faz previsões e armazena em cache as correspondências em segundo plano, o usuário pode continuar clicando em links para páginas em cache.
Opções de design
Confira algumas opções de design a serem consideradas, dependendo do caso de uso:
Tamanho da página do app. As páginas do app podem conter mais ou menos de 20 correspondências, se for adequado ao seu caso de uso. Lembre-se de que páginas menores carregam mais rápido e que muitos links em uma página podem ser difíceis de gerenciar para o usuário.
Atualizar o total de pesquisas. Enquanto o app está fazendo a pré-busca e armazenando em cache os resultados da pesquisa em segundo plano, você pode mostrar totais de pesquisa mais precisos ao usuário. Para fazer isso, configure o app para fazer o seguinte:
Em um intervalo definido, receba o total de pesquisa (a propriedade
Bundle.total
) do último pré-carregamento na camada de armazenamento em cache. Essa é a melhor estimativa atual do total de pesquisas. Mostre o total de pesquisa para o usuário, indicando que é uma estimativa. Determine a frequência dessa atualização com base no seu caso de uso.Reconhecer quando o total da pesquisa da camada de armazenamento em cache é preciso. Ou seja, o total da pesquisa é da última página dos resultados da pesquisa. Quando a última página de resultados da pesquisa é alcançada, o app mostra o total da pesquisa e indica ao usuário que o total da pesquisa é preciso. O app para de receber totais de pesquisa da camada de armazenamento em cache.
Com um grande número de correspondências, o prefetch em segundo plano e o armazenamento em cache podem não alcançar a última página dos resultados da pesquisa (e o total de pesquisa exato) antes que o usuário conclua a sessão de pesquisa.
Práticas recomendadas
Eliminar recursos duplicados incluídos. Se você usar os parâmetros
_include
e_revinclude
ao fazer precarregar e armazenar em cache os resultados da pesquisa, recomendamos duplicar os recursos incluídos no cache após cada precarga. Isso vai ajudar a economizar memória, reduzindo o tamanho do cache. Ao agrupar correspondências em páginas de apps, adicione os recursos incluídos adequados a cada página de app. Para mais informações, consulte Incluir outros recursos nos resultados da pesquisa.Defina um limite para a pré-busca e o armazenamento em cache. Com um número muito grande de resultados de pesquisa, pode ser impraticável ou impossível fazer o pré-carregamento de todos. Recomendamos definir um limite no número de resultados da pesquisa para pré-carregar. Isso mantém o cache em um tamanho gerenciável e ajuda a economizar memória. Por exemplo, é possível limitar o tamanho do cache a 10.000 ou 20.000 correspondências. Como alternativa, limite o número de páginas para pré-carregar ou defina um limite de tempo após o qual o pré-carregamento será interrompido. O tipo de limite imposto e a forma como ele é imposto são decisões de design que dependem do seu caso de uso. Se o limite for atingido antes que todos os resultados da pesquisa forem retornados, indique isso ao usuário, incluindo que o total da pesquisa ainda é uma estimativa.
Armazenamento em cache do front-end
O front-end do aplicativo, como um navegador da Web ou um app para dispositivos móveis, pode fornecer algum cache de resultados de pesquisa como uma alternativa para introduzir uma camada de cache na arquitetura. Essa abordagem pode fornecer navegação para a página anterior ou qualquer página no histórico de navegação, aproveitando chamadas AJAX e armazenando resultados de pesquisa e/ou URLs de paginação. Confira algumas vantagens dessa abordagem:
- Ela pode consumir menos recursos do que uma camada de armazenamento em cache.
- Ele é mais escalonável, porque distribui o trabalho de armazenamento em cache para vários clientes.
- É mais fácil determinar quando os recursos em cache não são mais necessários, por exemplo, quando o usuário fecha uma guia ou sai da interface de pesquisa.
Práticas recomendadas gerais
Confira algumas práticas recomendadas que se aplicam a todas as soluções neste documento.
Planeje páginas menores que o valor de _count. Em algumas circunstâncias, uma pesquisa pode retornar páginas com menos correspondências do que o valor
_count
especificado. Isso pode acontecer se você especificar um tamanho de página muito grande. Se a pesquisa retornar uma página menor que o valor de_count
e o app usar uma camada de armazenamento em cache, talvez seja necessário decidir se você quer (1) mostrar menos resultados do que o esperado em uma página do app ou (2) buscar mais alguns resultados para ter o suficiente para uma página completa do app. Para mais informações, consulte Paginação e classificação.Tente novamente os erros de solicitação HTTP que permitem uma nova tentativa. O app precisa esperar erros de solicitação HTTP repetíveis, como
429
ou500
, e tentar novamente após recebê-los.
Avaliar seus casos de uso
A implementação de recursos como navegar para qualquer página, obter totais de pesquisa precisos e atualizar totais estimados aumenta a complexidade e os custos de desenvolvimento do app. Esses recursos também podem aumentar a latência e os custos monetários para o uso de recursos do Google Cloud. Recomendamos avaliar cuidadosamente seus casos de uso para garantir que o valor desses recursos justifique os custos. Confira alguns pontos a serem considerados:
Navegar até qualquer página. Normalmente, o usuário não precisa navegar até uma página específica, mas até muitas páginas da página atual. Na maioria dos casos, navegar para uma página próxima é adequado.
Total de pesquisas precisas. Os totais de pesquisa podem mudar à medida que os recursos na armazenagem FHIR são criados, atualizados e excluídos. Por esse motivo, um total de pesquisa preciso é preciso no momento em que é retornado (com a última página dos resultados da pesquisa), mas pode não permanecer preciso ao longo do tempo. Portanto, os totais de pesquisa precisos podem ter um valor limitado para seu app, dependendo do caso de uso.