Me pregunto si es posible obtener varios documentos por lista de identificadores en un viaje de ida y vuelta (llamada de red) a Firestore.
101
Me pregunto si es posible obtener varios documentos por lista de identificadores en un viaje de ida y vuelta (llamada de red) a Firestore.
a
,b
,c
hacer algo. Solicito los tres en paralelo en solicitudes separadas.a
tarda 100 ms,b
150 ms yc
3000 ms. Como resultado, necesito esperar 3000ms para realizar la tarea. Va a sermax
de ellos. Va a ser más arriesgado cuando la cantidad de documentos a buscar es grande. Depende del estado de la red, creo que esto puede convertirse en un problema.SELECT * FROM docs WHERE id IN (a,b,c)
embargo, ¿no tomaría la misma cantidad de tiempo enviarlos todos como uno solo ? No veo la diferencia, ya que la conexión se establece una vez y el resto se canaliza sobre eso. El tiempo (después del establecimiento inicial de la conexión) es el tiempo de carga de todos los documentos + 1 viaje de ida y vuelta, el mismo para ambos enfoques. Si se comporta diferente para usted, ¿puede compartir una muestra (como en mi pregunta vinculada)?Respuestas:
si estás dentro del nodo:
https://github.com/googleapis/nodejs-firestore/blob/master/dev/src/index.ts#L701
Esto es específicamente para el SDK del servidor.
ACTUALIZACIÓN: "¡Cloud Firestore [sdk del lado del cliente] ahora admite consultas IN!"
https://firebase.googleblog.com/2019/11/cloud-firestore-now-supports-in-queries.html
myCollection.where(firestore.FieldPath.documentId(), 'in', ["123","456","789"])
fuente
firebase.firestore.FieldPath.documentId()
y no'id'
Acaban de anunciar esta funcionalidad, https://firebase.googleblog.com/2019/11/cloud-firestore-now-supports-in-queries.html .
Ahora puede usar consultas como, pero tenga en cuenta que el tamaño de entrada no puede ser mayor que 10.
userCollection.where('uid', 'in', ["1231","222","2131"])
fuente
db.collection('users').where(firebase.firestore.FieldPath.documentId(), 'in',["123","345","111"]).get()
firebase.firestore.FieldPath.documentId()
No, en este momento no hay forma de agrupar varias solicitudes de lectura con el SDK de Cloud Firestore y, por lo tanto, no hay forma de garantizar que pueda leer todos los datos a la vez.
Sin embargo, como ha dicho Frank van Puffelen en los comentarios anteriores, esto no significa que obtener 3 documentos será 3 veces más lento que obtener un documento. Es mejor realizar sus propias mediciones antes de llegar a una conclusión aquí.
fuente
En la práctica, usaría firestore.getAll así
o con sintaxis de promesa
fuente
Podrías usar una función como esta:
Se puede llamar con un solo ID:
o una serie de ID:
fuente
Sin duda, la mejor manera de hacerlo es implementando la consulta real de Firestore en una función de nube. Entonces solo habría una única llamada de ida y vuelta desde el cliente a Firebase, que parece ser lo que está pidiendo.
Realmente desea mantener toda su lógica de acceso a datos como este lado del servidor de todos modos.
Internamente, probablemente habrá la misma cantidad de llamadas a Firebase, pero todas serían a través de las interconexiones súper rápidas de Google, en lugar de la red externa, y combinadas con la canalización que Frank van Puffelen ha explicado, debería obtener un excelente rendimiento de Este enfoque.
fuente
Si está usando flutter, puede hacer lo siguiente:
Esto devolverá un futuro
List<DocumentSnapshot>
que contiene que puede iterar como mejor le parezca.fuente
Así es como haría algo como esto en Kotlin con el SDK de Android.
Puede que no sea necesariamente en un viaje de ida y vuelta, pero agrupa eficazmente el resultado y evita muchas devoluciones de llamada anidadas.
Tenga en cuenta que buscar documentos específicos es mucho mejor que buscar todos los documentos y filtrar el resultado. Esto se debe a que Firestore le cobra por el conjunto de resultados de la consulta.
fuente
Esto no parece ser posible en Firestore en este momento. No entiendo por qué se acepta la respuesta de Alexander, la solución que propone simplemente devuelve todos los documentos de la colección "usuarios".
Dependiendo de lo que deba hacer, debe buscar duplicar los datos relevantes que necesita mostrar y solo solicitar un documento completo cuando sea necesario.
fuente
Lo mejor que puede hacer es no usarlo
Promise.all
como su cliente, luego debe esperar.all
las lecturas antes de continuar.Repite las lecturas y deja que se resuelvan de forma independiente. En el lado del cliente, esto probablemente se reduce a que la interfaz de usuario tiene varias imágenes del cargador de progreso que se resuelven en valores de forma independiente. Sin embargo, esto es mejor que congelar a todo el cliente hasta
.all
resuelvan las lecturas.Por lo tanto, descargue todos los resultados síncronos en la vista inmediatamente, luego deje que los resultados asincrónicos entren a medida que se resuelven, individualmente. Esto puede parecer una distinción insignificante, pero si su cliente tiene una mala conectividad a Internet (como la que tengo actualmente en esta cafetería), congelar toda la experiencia del cliente durante varios segundos probablemente resultará en una experiencia de 'esta aplicación apesta'.
fuente
Promise.all
... no necesariamente tiene que "congelar" nada; es posible que deba esperar todos los datos antes de poder hacer algo significativoEspero que esto te ayude, me funciona.
fuente