Saya ingin tahu apakah mungkin untuk mendapatkan banyak dokumen dengan daftar id dalam satu perjalanan (panggilan jaringan) ke Firestore.
105
Saya ingin tahu apakah mungkin untuk mendapatkan banyak dokumen dengan daftar id dalam satu perjalanan (panggilan jaringan) ke Firestore.
a
,b
,c
untuk melakukan sesuatu. Saya meminta ketiganya secara paralel dalam permintaan terpisah.a
membutuhkan 100ms,b
membutuhkan 150ms, danc
membutuhkan 3000ms. Akibatnya, saya harus menunggu 3000ms untuk melakukan tugas tersebut. Itu akan menjadi salahmax
satu dari mereka. Ini akan lebih berisiko bila jumlah dokumen yang akan diambil banyak. Bergantung pada status jaringan, saya rasa ini bisa menjadi masalah.SELECT * FROM docs WHERE id IN (a,b,c)
membutuhkan waktu yang sama? Saya tidak melihat perbedaannya, karena koneksi dibuat satu kali dan sisanya terhubung dengan pipa. Waktu (setelah pembuatan awal koneksi) adalah waktu buka semua dokumen + 1 perjalanan pulang pergi, sama untuk kedua pendekatan. Jika perilakunya berbeda untuk Anda, dapatkah Anda membagikan sampel (seperti dalam pertanyaan tertaut saya)?Jawaban:
jika Anda berada dalam Node:
https://github.com/googleapis/nodejs-firestore/blob/master/dev/src/index.ts#L701
Ini khusus untuk SDK server
PEMBARUAN: "Cloud Firestore [client-side sdk] Sekarang Mendukung Kueri DI!"
https://firebase.googleblog.com/2019/11/cloud-firestore-now-supports-in-queries.html
myCollection.where(firestore.FieldPath.documentId(), 'in', ["123","456","789"])
sumber
firebase.firestore.FieldPath.documentId()
dan tidak'id'
Mereka baru saja mengumumkan fungsi ini, https://firebase.googleblog.com/2019/11/cloud-firestore-now-supports-in-queries.html .
Sekarang Anda dapat menggunakan kueri seperti, tetapi perlu diingat bahwa ukuran input tidak boleh lebih dari 10.
userCollection.where('uid', 'in', ["1231","222","2131"])
sumber
db.collection('users').where(firebase.firestore.FieldPath.documentId(), 'in',["123","345","111"]).get()
firebase.firestore.FieldPath.documentId()
Dalam praktiknya, Anda akan menggunakan firestore.getAll seperti ini
atau dengan sintaks janji
sumber
Tidak, saat ini tidak ada cara untuk mengumpulkan beberapa permintaan baca menggunakan Cloud Firestore SDK dan oleh karena itu tidak ada cara untuk menjamin bahwa Anda dapat membaca semua data sekaligus.
Namun seperti yang dikatakan Frank van Puffelen dalam komentar di atas, ini tidak berarti bahwa mengambil 3 dokumen akan menjadi 3x lebih lambat dari mengambil satu dokumen. Sebaiknya lakukan pengukuran Anda sendiri sebelum mencapai kesimpulan di sini.
sumber
Anda bisa menggunakan fungsi seperti ini:
Itu bisa dipanggil dengan satu ID:
atau serangkaian ID:
sumber
Tentunya cara terbaik untuk melakukannya adalah dengan mengimplementasikan kueri Firestore yang sebenarnya di Cloud Function? Kemudian hanya akan ada satu panggilan pulang pergi dari klien ke Firebase, yang tampaknya menjadi apa yang Anda minta.
Anda benar-benar ingin menyimpan semua logika akses data Anda seperti sisi server ini.
Secara internal kemungkinan akan ada jumlah panggilan yang sama ke Firebase itu sendiri, tetapi semuanya akan berada di seluruh interkoneksi super cepat Google, bukan jaringan eksternal, dan dikombinasikan dengan pipelining yang dijelaskan oleh Frank van Puffelen, Anda akan mendapatkan kinerja yang sangat baik dari pendekatan ini.
sumber
Jika Anda menggunakan flutter, Anda dapat melakukan hal berikut:
Ini akan mengembalikan Masa Depan yang berisi
List<DocumentSnapshot>
yang dapat Anda ulangi sesuai keinginan Anda.sumber
Inilah cara Anda melakukan hal seperti ini di Kotlin dengan Android SDK.
Mungkin tidak harus dilakukan dalam satu perjalanan pulang pergi, tetapi ini mengelompokkan hasil secara efektif dan menghindari banyak callback bersarang.
Perhatikan bahwa mengambil dokumen tertentu jauh lebih baik daripada mengambil semua dokumen dan memfilter hasilnya. Ini karena Firestore menagih Anda untuk kumpulan hasil kueri.
sumber
Saya harap ini membantu Anda, ini berhasil untuk saya.
sumber
Ini sepertinya tidak mungkin dilakukan di Firestore saat ini. Saya tidak mengerti mengapa jawaban Alexander diterima, solusi yang dia usulkan hanya mengembalikan semua dokumen dalam koleksi "pengguna".
Bergantung pada apa yang perlu Anda lakukan, Anda harus mencari duplikat data relevan yang perlu Anda tampilkan dan hanya meminta dokumen lengkap saat diperlukan.
sumber
Yang terbaik yang dapat Anda lakukan adalah tidak menggunakannya
Promise.all
karena klien Anda harus menunggu.all
pembacaan sebelum melanjutkan.Ulangi bacaan dan biarkan mereka menyelesaikannya sendiri. Di sisi klien, ini mungkin bermuara pada UI yang memiliki beberapa gambar pemuat kemajuan yang diselesaikan ke nilai secara independen. Namun, ini lebih baik daripada membekukan seluruh klien sampai
.all
pembacaan selesai.Oleh karena itu, segera buang semua hasil sinkron ke tampilan, lalu biarkan hasil asinkron masuk saat diselesaikan, satu per satu. Ini mungkin tampak seperti perbedaan kecil, tetapi jika klien Anda memiliki konektivitas Internet yang buruk (seperti yang saya miliki saat ini di kedai kopi ini), membekukan seluruh pengalaman klien selama beberapa detik kemungkinan akan menghasilkan pengalaman 'aplikasi ini menyebalkan'.
sumber
Promise.all
... tidak perlu "membekukan" apa pun - Anda mungkin perlu menunggu semua data sebelum Anda dapat melakukan sesuatu yang berarti