Ich frage mich, ob es möglich ist, mehrere Dokumente anhand der ID-Liste in einer Hin- und Rückfahrt (Netzwerkanruf) zum Firestore abzurufen.
98
Ich frage mich, ob es möglich ist, mehrere Dokumente anhand der ID-Liste in einer Hin- und Rückfahrt (Netzwerkanruf) zum Firestore abzurufen.
a
,b
,c
etwas zu tun. Ich fordere alle drei parallel in getrennten Anfragen an.a
dauert 100 ms,b
dauert 150 ms undc
dauert 3000 ms. Daher muss ich auf 3000 ms warten, um die Aufgabe zu erledigen. Es wirdmax
von ihnen sein. Es wird riskanter, wenn die Anzahl der abzurufenden Dokumente groß ist. Abhängig vom Netzwerkstatus denke ich, dass dies zu einem Problem werden kann.SELECT * FROM docs WHERE id IN (a,b,c)
dauern , sie alle als Single zu senden ? Ich sehe keinen Unterschied, da die Verbindung einmal hergestellt wird und der Rest darüber geleitet wird. Die Zeit (nach dem ersten Verbindungsaufbau) ist die Ladezeit aller Dokumente + 1 Hin- und Rückfahrt, für beide Ansätze gleich. Wenn es sich für Sie anders verhält, können Sie ein Beispiel teilen (wie in meiner verknüpften Frage)?Antworten:
Wenn Sie sich innerhalb des Knotens befinden:
https://github.com/googleapis/nodejs-firestore/blob/master/dev/src/index.ts#L701
Dies ist speziell für das Server-SDK
UPDATE: "Cloud Firestore [clientseitiges SDK] unterstützt jetzt IN-Abfragen!"
https://firebase.googleblog.com/2019/11/cloud-firestore-now-supports-in-queries.html
myCollection.where(firestore.FieldPath.documentId(), 'in', ["123","456","789"])
quelle
firebase.firestore.FieldPath.documentId()
und nicht'id'
Sie haben gerade diese Funktionalität angekündigt, https://firebase.googleblog.com/2019/11/cloud-firestore-now-supports-in-queries.html .
Jetzt können Sie Abfragen wie verwenden, aber beachten Sie, dass die Eingabegröße nicht größer als 10 sein darf.
userCollection.where('uid', 'in', ["1231","222","2131"])
quelle
db.collection('users').where(firebase.firestore.FieldPath.documentId(), 'in',["123","345","111"]).get()
firebase.firestore.FieldPath.documentId()
Nein, derzeit gibt es keine Möglichkeit, mehrere Leseanforderungen mit dem Cloud Firestore SDK zu stapeln, und daher keine Möglichkeit, sicherzustellen, dass Sie alle Daten gleichzeitig lesen können.
Wie Frank van Puffelen in den obigen Kommentaren gesagt hat, bedeutet dies jedoch nicht, dass das Abrufen von 3 Dokumenten dreimal so langsam ist wie das Abrufen eines Dokuments. Es ist am besten, eigene Messungen durchzuführen, bevor Sie hier zu einer Schlussfolgerung gelangen.
quelle
In der Praxis würden Sie firestore.getAll so verwenden
oder mit Versprechenssyntax
quelle
Sie könnten eine Funktion wie diese verwenden:
Es kann mit einer einzigen ID aufgerufen werden:
oder ein Array von IDs:
quelle
Der beste Weg, dies zu tun, ist sicherlich die Implementierung der eigentlichen Abfrage von Firestore in einer Cloud-Funktion. Es würde dann nur einen einzigen Hin- und Rückruf vom Kunden zu Firebase geben, was genau das zu sein scheint, wonach Sie fragen.
Sie möchten wirklich Ihre gesamte Datenzugriffslogik wie diese Serverseite beibehalten.
Intern wird es wahrscheinlich die gleiche Anzahl von Anrufen bei Firebase selbst geben, aber alle werden über die superschnellen Verbindungen von Google und nicht über das externe Netzwerk erfolgen. In Kombination mit dem von Frank van Puffelen erläuterten Pipelining sollten Sie eine hervorragende Leistung erzielen dieser Ansatz.
quelle
Wenn Sie Flattern verwenden, können Sie Folgendes tun:
Dies gibt eine Zukunft zurück,
List<DocumentSnapshot>
die Sie wiederholen können, wenn Sie sich fit fühlen.quelle
So würden Sie in Kotlin mit dem Android SDK so etwas machen.
Möglicherweise nicht unbedingt in einer Hin- und Rückfahrt, aber es gruppiert das Ergebnis effektiv und vermeidet viele verschachtelte Rückrufe.
Beachten Sie, dass das Abrufen bestimmter Dokumente viel besser ist als das Abrufen aller Dokumente und das Filtern des Ergebnisses. Dies liegt daran, dass Firestore Ihnen die Abfrageergebnismenge in Rechnung stellt.
quelle
Dies scheint im Firestore derzeit nicht möglich zu sein. Ich verstehe nicht, warum Alexanders Antwort akzeptiert wird. Die von ihm vorgeschlagene Lösung gibt nur alle Dokumente in der Sammlung "Benutzer" zurück.
Je nachdem, was Sie tun müssen, sollten Sie die relevanten Daten, die Sie anzeigen müssen, duplizieren und nur bei Bedarf ein vollständiges Dokument anfordern.
quelle
Das Beste, was Sie tun können, ist, es nicht zu verwenden,
Promise.all
da Ihr Client darauf warten muss.all
die Lesevorgänge bevor Sie fortfahren.Iterieren Sie die Lesevorgänge und lassen Sie sie unabhängig voneinander auflösen. Auf der Clientseite läuft dies wahrscheinlich darauf hinaus, dass die Benutzeroberfläche mehrere Progress Loader-Images unabhängig voneinander in Werte auflöst. Dies ist jedoch besser als das Einfrieren des gesamten Clients bis
.all
die Lesevorgänge aufgelöst sind.Speichern Sie daher alle synchronen Ergebnisse sofort in der Ansicht und lassen Sie die asynchronen Ergebnisse einzeln beim Auflösen eingehen. Dies mag wie eine geringfügige Unterscheidung erscheinen, aber wenn Ihr Client über eine schlechte Internetverbindung verfügt (wie ich sie derzeit in diesem Café habe), führt das Einfrieren der gesamten Client-Erfahrung für einige Sekunden wahrscheinlich zu einer "Diese App ist zum Kotzen" -Erfahrung.
quelle
Promise.all
... es muss nicht unbedingt irgendetwas "einfrieren" - Sie müssen möglicherweise auf alle Daten warten, bevor Sie etwas Sinnvolles tun könnenIch hoffe das hilft dir, es funktioniert bei mir.
quelle