Gostaria de saber se é possível obter vários documentos por lista de ids em uma viagem de ida e volta (chamada de rede) para o Firestore.
98
Gostaria de saber se é possível obter vários documentos por lista de ids em uma viagem de ida e volta (chamada de rede) para o Firestore.
a
,b
,c
fazer alguma coisa. I pedidos para todos os três em paralelo em pedidos separados.a
leva 100ms,b
leva 150ms ec
leva 3000ms. Como resultado, preciso esperar 3000ms para fazer a tarefa. Vai sermax
deles. Vai ser mais arriscado quando o número de documentos a buscar é grande. Depende do status da rede, acho que isso pode se tornar um problema.SELECT * FROM docs WHERE id IN (a,b,c)
entanto, enviar todos juntos não levaria o mesmo tempo? Não vejo diferença, já que a conexão é estabelecida uma vez e o resto é canalizado sobre isso. O tempo (após o estabelecimento inicial da conexão) é o tempo de carregamento de todos os documentos + 1 ida e volta, o mesmo para ambas as abordagens. Se ele se comportar de forma diferente para você, você pode compartilhar uma amostra (como na minha pergunta vinculada)?Respostas:
se você estiver dentro do Node:
https://github.com/googleapis/nodejs-firestore/blob/master/dev/src/index.ts#L701
Isso é especificamente para o SDK do servidor
ATUALIZAÇÃO: "Cloud Firestore [client-side sdk] agora oferece suporte a consultas IN!"
https://firebase.googleblog.com/2019/11/cloud-firestore-now-supports-in-queries.html
myCollection.where(firestore.FieldPath.documentId(), 'in', ["123","456","789"])
fonte
firebase.firestore.FieldPath.documentId()
e não'id'
Eles acabaram de anunciar essa funcionalidade, https://firebase.googleblog.com/2019/11/cloud-firestore-now-supports-in-queries.html .
Agora você pode usar consultas como, mas lembre-se de que o tamanho da entrada não pode ser maior que 10.
userCollection.where('uid', 'in', ["1231","222","2131"])
fonte
db.collection('users').where(firebase.firestore.FieldPath.documentId(), 'in',["123","345","111"]).get()
firebase.firestore.FieldPath.documentId()
Não, no momento não há como agrupar várias solicitações de leitura usando o SDK do Cloud Firestore e, portanto, não há como garantir que você possa ler todos os dados de uma vez.
No entanto, como Frank van Puffelen disse nos comentários acima, isso não significa que buscar 3 documentos será 3x mais lento do que buscar um documento. É melhor realizar suas próprias medições antes de chegar a uma conclusão aqui.
fonte
Na prática, você usaria firestore.getAll assim
ou com sintaxe de promessa
fonte
Você poderia usar uma função como esta:
Ele pode ser chamado com um único ID:
ou uma matriz de IDs:
fonte
Certamente, a melhor maneira de fazer isso é implementando a consulta real do Firestore em um Cloud Function. Haveria então apenas uma única chamada de ida e volta do cliente para o Firebase, que parece ser o que você está pedindo.
Você realmente deseja manter toda a sua lógica de acesso a dados como este lado do servidor de qualquer maneira.
Internamente, provavelmente haverá o mesmo número de chamadas para o próprio Firebase, mas todas elas seriam através das interconexões super-rápidas do Google, ao invés da rede externa, e combinadas com o pipelining que Frank van Puffelen explicou, você deve obter um excelente desempenho esta abordagem.
fonte
Se estiver usando flutter, você pode fazer o seguinte:
Isso retornará um Future contendo o
List<DocumentSnapshot>
qual você pode iterar conforme achar adequado.fonte
Veja como você faria algo assim em Kotlin com o Android SDK.
Pode não ser necessariamente em uma viagem de ida e volta, mas efetivamente agrupa o resultado e evita muitos retornos de chamada aninhados.
Observe que buscar documentos específicos é muito melhor do que buscar todos os documentos e filtrar o resultado. Isso ocorre porque o Firestore cobra pelo conjunto de resultados da consulta.
fonte
Isso não parece ser possível no Firestore no momento. Não entendo por que a resposta de Alexander é aceita, a solução que ele propõe apenas retorna todos os documentos da coleção "usuários".
Dependendo do que você precisa fazer, você deve tentar duplicar os dados relevantes que você precisa exibir e só solicitar um documento completo quando necessário.
fonte
O melhor que você pode fazer é não usar
Promise.all
como seu cliente, então deve esperar pelas.all
leituras antes de continuar.Repita as leituras e deixe-as resolver de forma independente. No lado do cliente, isso provavelmente se resume à interface do usuário com várias imagens do carregador de progresso resolvidas para valores independentemente. No entanto, isso é melhor do que congelar todo o cliente até
.all
as leituras sejam resolvidas.Portanto, despeje todos os resultados síncronos na exibição imediatamente e deixe os resultados assíncronos chegarem conforme eles são resolvidos, individualmente. Isso pode parecer uma distinção mesquinha, mas se o seu cliente não tiver conectividade com a Internet (como eu tenho atualmente nesta cafeteria), congelar toda a experiência do cliente por vários segundos provavelmente resultará em uma experiência 'este aplicativo é uma merda'.
fonte
Promise.all
... ele não precisa necessariamente "congelar" nada - você pode precisar esperar por todos os dados antes de fazer algo significativoEspero que isso ajude você, funciona para mim.
fonte