Je me demande s'il est possible d'obtenir plusieurs documents par liste d'identifiants en un aller-retour (appel réseau) au Firestore.
98
Je me demande s'il est possible d'obtenir plusieurs documents par liste d'identifiants en un aller-retour (appel réseau) au Firestore.
a
,b
,c
de faire quelque chose. Je demande les trois en parallèle dans des demandes distinctes.a
prendb
100 ms,c
prend 150 ms et prend 3000 ms. En conséquence, je dois attendre 3000 ms pour faire la tâche. Ça va êtremax
d'eux. Ce sera plus risqué lorsque le nombre de documents à récupérer sera important. Cela dépend de l'état du réseau, je pense que cela peut devenir un problème.SELECT * FROM docs WHERE id IN (a,b,c)
prendrait-il pas le même temps? Je ne vois pas la différence, car la connexion est établie une fois et le reste est acheminé à ce sujet. Le temps (après l'établissement initial de la connexion) est le temps de chargement de tous les documents + 1 aller-retour, identique pour les deux approches. S'il se comporte différemment pour vous, pouvez-vous partager un échantillon (comme dans ma question liée)?Réponses:
si vous êtes dans Node:
https://github.com/googleapis/nodejs-firestore/blob/master/dev/src/index.ts#L701
Ceci est spécifiquement pour le SDK du serveur
MISE À JOUR: «Cloud Firestore [sdk côté client] prend désormais en charge les requêtes IN!»
https://firebase.googleblog.com/2019/11/cloud-firestore-now-supports-in-queries.html
myCollection.where(firestore.FieldPath.documentId(), 'in', ["123","456","789"])
la source
firebase.firestore.FieldPath.documentId()
et non'id'
Ils viennent d'annoncer cette fonctionnalité, https://firebase.googleblog.com/2019/11/cloud-firestore-now-supports-in-queries.html .
Vous pouvez maintenant utiliser des requêtes comme, mais sachez que la taille d'entrée ne peut pas être supérieure à 10.
userCollection.where('uid', 'in', ["1231","222","2131"])
la source
db.collection('users').where(firebase.firestore.FieldPath.documentId(), 'in',["123","345","111"]).get()
firebase.firestore.FieldPath.documentId()
Non, pour le moment, il n'existe aucun moyen de regrouper plusieurs demandes de lecture à l'aide du SDK Cloud Firestore et donc aucun moyen de garantir que vous pouvez lire toutes les données à la fois.
Cependant, comme Frank van Puffelen l'a dit dans les commentaires ci-dessus, cela ne signifie pas que la récupération de 3 documents sera 3 fois plus lente que la récupération d'un document. Il est préférable d'effectuer vos propres mesures avant d'arriver à une conclusion ici.
la source
En pratique, vous utiliseriez firestore.getAll comme ça
ou avec la syntaxe de promesse
la source
Vous pouvez utiliser une fonction comme celle-ci:
Il peut être appelé avec un seul identifiant:
ou un tableau d'identifiants:
la source
La meilleure façon de le faire est sûrement d'implémenter la requête réelle de Firestore dans une fonction cloud? Il n'y aurait alors qu'un seul appel aller-retour du client à Firebase, ce qui semble être ce que vous demandez.
Vous voulez vraiment conserver toute votre logique d'accès aux données comme ce côté serveur de toute façon.
En interne, il y aura probablement le même nombre d'appels à Firebase lui-même, mais ils seraient tous via les interconnexions ultra-rapides de Google, plutôt que le réseau externe, et combinés avec le pipeline que Frank van Puffelen a expliqué, vous devriez obtenir d'excellentes performances de cette approche.
la source
Si vous utilisez le flutter, vous pouvez effectuer les opérations suivantes:
Cela renverra un Future contenant
List<DocumentSnapshot>
que vous pourrez itérer à votre guise.la source
Voici comment vous feriez quelque chose comme ça dans Kotlin avec le SDK Android.
Cela peut ne pas être nécessairement en un aller-retour, mais cela regroupe efficacement le résultat et évite de nombreux rappels imbriqués.
Notez que la récupération de documents spécifiques est bien meilleure que la récupération de tous les documents et le filtrage du résultat. En effet, Firestore vous facture le jeu de résultats de la requête.
la source
Cela ne semble pas possible dans Firestore pour le moment. Je ne comprends pas pourquoi la réponse d'Alexandre est acceptée, la solution qu'il propose renvoie simplement tous les documents de la collection «utilisateurs».
En fonction de ce que vous devez faire, vous devriez envisager de dupliquer les données pertinentes que vous devez afficher et ne demander un document complet que lorsque cela est nécessaire.
la source
Le mieux que vous puissiez faire est de ne pas utiliser
Promise.all
car votre client doit alors attendre.all
les lectures avant de continuer.Répétez les lectures et laissez-les se résoudre indépendamment. Du côté client, cela se résume probablement à l'interface utilisateur ayant plusieurs images du chargeur de progression résolues en valeurs indépendamment. Cependant, c'est mieux que de geler l'ensemble du client jusqu'à
.all
ce que les lectures soient résolues.Par conséquent, videz immédiatement tous les résultats synchrones dans la vue, puis laissez les résultats asynchrones entrer au fur et à mesure de leur résolution, individuellement. Cela peut sembler insignifiant, mais si votre client a une mauvaise connectivité Internet (comme je l'ai actuellement dans ce café), geler toute l'expérience client pendant plusieurs secondes entraînera probablement une expérience `` cette application est nul ''.
la source
Promise.all
... il n'est pas nécessaire de "geler" quoi que ce soit - vous devrez peut-être attendre toutes les données avant de pouvoir faire quelque chose de significatifJ'espère que cela vous aide, cela fonctionne pour moi.
la source