Apakah mungkin untuk menghitung berapa banyak item koleksi telah menggunakan basis data Firebase baru, Cloud Firestore?
Jika demikian, bagaimana saya melakukannya?
firebase
google-cloud-firestore
Guilherme Torres Castro
sumber
sumber
Jawaban:
Pembaruan (April 2019) - FieldValue.increment (lihat solusi koleksi besar)
Seperti banyak pertanyaan, jawabannya adalah - Itu tergantung .
Anda harus sangat berhati-hati saat menangani sejumlah besar data di ujung depan. Selain membuat ujung depan Anda terasa lamban, Firestore juga menagih Anda $ 0,60 per juta bacaan yang Anda buat.
Koleksi kecil (kurang dari 100 dokumen)
Gunakan dengan hati-hati - Pengalaman pengguna Frontend mungkin terpukul
Menangani ini di ujung depan harus baik-baik saja selama Anda tidak melakukan terlalu banyak logika dengan array yang dikembalikan ini.
Koleksi sedang (100 hingga 1000 dokumen)
Gunakan dengan hati-hati - doa baca Firestore mungkin sangat mahal
Menangani ini di ujung depan tidak layak karena memiliki terlalu banyak potensi untuk memperlambat sistem pengguna. Kita harus menangani sisi server logika ini dan hanya mengembalikan ukurannya.
Kelemahan dari metode ini adalah Anda masih menggunakan bacaan firestore (sama dengan ukuran koleksi Anda), yang dalam jangka panjang mungkin berakhir dengan biaya lebih dari yang diharapkan.
Fungsi cloud:
Paling depan:
Koleksi besar (1000+ dokumen)
Solusi yang paling scalable
Pada April 2019 Firestore sekarang memungkinkan penghitung yang bertambah, sepenuhnya atom, dan tanpa membaca data sebelumnya . Ini memastikan kami memiliki nilai penghitung yang benar bahkan ketika memperbarui dari berbagai sumber secara bersamaan (sebelumnya diselesaikan dengan menggunakan transaksi), sambil juga mengurangi jumlah bacaan basis data yang kami lakukan.
Dengan mendengarkan setiap dokumen yang dihapus atau dibuat, kami dapat menambah atau menghapus dari bidang jumlah yang ada di database.
Lihat dokumen firestore - Penghitung Terdistribusi Atau lihat Agregasi Data oleh Jeff Delaney. Panduannya benar-benar fantastis bagi siapa saja yang menggunakan AngularFire, tetapi pelajarannya harus dibawa ke kerangka kerja lain juga.
Fungsi cloud:
Sekarang di frontend Anda bisa menanyakan bidang numberOfDocs ini untuk mendapatkan ukuran koleksi.
sumber
firestore.runTransaction { ... }
blok. Ini memperbaiki masalah konkurensi dengan mengaksesnumberOfDocs
.Cara paling sederhana untuk melakukannya adalah dengan membaca ukuran "querySnapshot".
Anda juga dapat membaca panjang array dokumen di dalam "querySnapshot".
Atau jika "querySnapshot" kosong dengan membaca nilai kosong, yang akan mengembalikan nilai boolean.
sumber
db.collection.count()
. Berpikir menjatuhkan mereka hanya untuk iniSejauh yang saya tahu tidak ada solusi built-in untuk ini dan hanya mungkin dalam node SDK sekarang. Jika Anda punya
kamu bisa memakai
untuk menentukan bidang mana yang ingin Anda pilih. Jika Anda melakukan pilih kosong () Anda hanya akan mendapatkan berbagai referensi dokumen.
contoh:
db.collection('someCollection').select().get().then( (snapshot) => console.log(snapshot.docs.length) );
Solusi ini hanya optimasi untuk kasus terburuk mengunduh semua dokumen dan tidak menskala koleksi besar!
Lihat juga ini:
Cara mendapatkan jumlah dokumen dalam koleksi dengan Cloud Firestore
sumber
select(['_id'])
lebih cepat dariselect()
Hati-hati menghitung jumlah dokumen untuk koleksi besar . Ini sedikit rumit dengan basis data firestore jika Anda ingin memiliki penghitung yang telah dihitung untuk setiap koleksi.
Kode seperti ini tidak berfungsi dalam hal ini:
Alasannya adalah karena setiap pemicu cloud firestore harus idempoten, seperti yang dikatakan dokumentasi firestore: https://firebase.google.com/docs/functions/firestore-events#limitations_and_guaraminan
Larutan
Jadi, untuk mencegah beberapa eksekusi kode Anda, Anda perlu mengelola dengan peristiwa dan transaksi. Ini adalah cara khusus saya untuk menangani penghitung koleksi besar:
Gunakan kasing di sini:
Seperti yang Anda lihat, kunci untuk mencegah beberapa eksekusi adalah properti yang disebut eventId di objek konteks. Jika fungsi telah ditangani berkali-kali untuk acara yang sama, id acara akan sama dalam semua kasus. Sayangnya, Anda harus memiliki koleksi "acara" di database Anda.
sumber
context.eventId
akan selalu sama pada banyak pemanggilan dengan pemicu yang sama? Dalam pengujian saya tampaknya konsisten, tetapi saya tidak dapat menemukan dokumentasi "resmi" yang menyatakan ini.Pada tahun 2020 ini masih belum tersedia di Firebase SDK namun tersedia di Firebase Extensions (Beta) namun cukup rumit untuk menyiapkan dan menggunakan ...
Pendekatan yang masuk akal
Pembantu ... (membuat / menghapus sepertinya berlebihan tetapi lebih murah daripada saat diperbarui)
Kait Firestore yang Diekspor
Beraksi
Kumpulan akar bangunan dan semua koleksi sub akan dilacak.
Di sini di bawah
/counters/
jalur rootSekarang jumlah koleksi akan diperbarui secara otomatis dan akhirnya! Jika Anda membutuhkan hitungan, cukup gunakan jalur pengumpulan dan awali dengan
counters
.sumber
Saya setuju dengan @Matthew, biayanya akan banyak jika Anda melakukan permintaan seperti itu.
[SARAN UNTUK PEMBANGUN SEBELUM MEMULAI PROYEKNYA]
Karena kami telah meramalkan situasi ini di awal, kami sebenarnya dapat membuat koleksi yaitu penghitung dengan dokumen untuk menyimpan semua penghitung di bidang dengan tipe
number
.Sebagai contoh:
Untuk setiap operasi CRUD pada koleksi, perbarui dokumen counter:
Lain kali, ketika Anda ingin mendapatkan jumlah koleksi, Anda hanya perlu query / arahkan ke bidang dokumen. [1 operasi baca]
Selain itu, Anda dapat menyimpan nama koleksi dalam array, tetapi ini akan sulit, kondisi array di firebase ditampilkan seperti di bawah ini:
Jadi, jika Anda tidak akan menghapus koleksi, Anda sebenarnya dapat menggunakan array untuk menyimpan daftar nama koleksi alih-alih menanyakan semua koleksi setiap waktu.
Semoga ini bisa membantu!
sumber
Tidak, tidak ada dukungan bawaan untuk permintaan agregasi sekarang. Namun ada beberapa hal yang bisa Anda lakukan.
Yang pertama didokumentasikan di sini . Anda dapat menggunakan transaksi atau fungsi cloud untuk mempertahankan informasi agregat:
Contoh ini menunjukkan cara menggunakan fungsi untuk melacak jumlah peringkat dalam subkoleksi, serta peringkat rata-rata.
Solusi yang disebutkan jbb juga berguna jika Anda hanya ingin jarang menghitung dokumen. Pastikan untuk menggunakan
select()
pernyataan untuk menghindari mengunduh semua dokumen (itu banyak bandwidth ketika Anda hanya perlu menghitung).select()
hanya tersedia di SDK server untuk saat ini sehingga solusi tidak akan berfungsi di aplikasi seluler.sumber
Tidak ada opsi langsung yang tersedia. Anda tidak bisa melakukannya
db.collection("CollectionName").count()
. Di bawah ini adalah dua cara dimana Anda dapat menemukan hitungan jumlah dokumen dalam koleksi.1: - Dapatkan semua dokumen dalam koleksi dan kemudian dapatkan ukurannya. (Bukan Solusi terbaik)
Dengan menggunakan kode di atas, bacaan dokumen Anda akan sama dengan ukuran dokumen dalam koleksi dan itulah alasan mengapa seseorang harus menghindari menggunakan solusi di atas.
2: - Buat dokumen terpisah dengan koleksi Anda yang akan menyimpan jumlah dokumen dalam koleksi. (Solusi Terbaik)
Di atas kami membuat dokumen dengan jumlah nama untuk menyimpan semua informasi jumlah. Anda dapat memperbarui dokumen jumlah dengan cara berikut: -
harga wrt (Document Read = 1) dan pengambilan data cepat solusi di atas adalah baik.
sumber
Tambahkan penghitung menggunakan admin.firestore.FieldValue.increment :
Dalam contoh ini kami menambah
instanceCount
bidang dalam proyek setiap kali dokumen ditambahkan keinstances
sub koleksi. Jika bidang belum ada, maka akan dibuat dan ditambahkan ke 1.Peningkatan ini bersifat transaksional secara internal tetapi Anda harus menggunakan penghitung terdistribusi jika Anda perlu menambah lebih sering daripada setiap 1 detik.
Ini sering lebih baik untuk diterapkan
onCreate
danonDelete
daripadaonWrite
Anda akan memintaonWrite
pembaruan yang berarti Anda menghabiskan lebih banyak uang untuk pemanggilan fungsi yang tidak perlu (jika Anda memperbarui dokumen dalam koleksi Anda).sumber
Solusi adalah untuk:
tulis penghitung di dokumen firebase, yang Anda tambahkan dalam transaksi setiap kali Anda membuat entri baru
Anda menyimpan hitungan di bidang entri baru Anda (yaitu: posisi: 4).
Kemudian Anda membuat indeks pada bidang itu (posisi DESC).
Anda dapat melakukan melewati batas + dengan kueri. Di mana ("posisi", "<" x) .OrderBy ("posisi", DESC)
Semoga ini membantu!
sumber
Saya membuat fungsi universal menggunakan semua ide ini untuk menangani semua situasi tandingan (kecuali kueri).
Ini menangani acara, kenaikan, dan transaksi. Keindahan dalam ini, adalah bahwa jika Anda tidak yakin tentang keakuratan dokumen (mungkin saat masih dalam versi beta), Anda dapat menghapus penghitung agar secara otomatis menambahkannya pada pemicu berikutnya. Ya, ini biayanya, jadi jangan hapus kalau tidak.
Hal yang sama untuk mendapatkan hitungan:
Selain itu, Anda mungkin ingin membuat pekerjaan cron (fungsi terjadwal) untuk menghapus acara lama untuk menghemat uang pada penyimpanan basis data. Anda memerlukan setidaknya paket blaze, dan mungkin ada beberapa konfigurasi lagi. Anda bisa menjalankannya setiap minggu pukul 11 malam, misalnya. https://firebase.google.com/docs/functions/schedule-functions
Ini belum diuji , tetapi harus bekerja dengan beberapa penyesuaian:
Dan terakhir, jangan lupa untuk melindungi koleksi di firestore.rules :
Perbarui: Permintaan
Menambahkan ke jawaban saya yang lain jika Anda ingin mengotomatiskan jumlah kueri juga, Anda dapat menggunakan kode yang dimodifikasi ini di fungsi cloud Anda:
Yang secara otomatis akan memperbarui postsCount di userDocument. Anda dapat dengan mudah menambahkan yang lain ke banyak hitungan dengan cara ini. Ini hanya memberi Anda ide tentang bagaimana Anda dapat mengotomatisasi sesuatu. Saya juga memberi Anda cara lain untuk menghapus acara. Anda harus membaca setiap tanggal untuk menghapusnya, jadi itu tidak benar-benar menyelamatkan Anda untuk menghapusnya nanti, hanya membuat fungsinya lebih lambat.
sumber
Butuh waktu beberapa saat untuk menyelesaikannya berdasarkan beberapa jawaban di atas, jadi saya pikir saya akan membagikannya untuk digunakan orang lain. Semoga bermanfaat.
sumber
Saya sudah mencoba banyak dengan pendekatan yang berbeda. Dan akhirnya, saya meningkatkan salah satu metode. Pertama, Anda perlu membuat koleksi terpisah dan menyimpan semua acara di sana. Kedua, Anda perlu membuat lambda baru untuk dipicu oleh waktu. Lambda ini akan Menghitung acara dalam koleksi acara dan menghapus dokumen acara. Rincian kode dalam artikel. https://medium.com/@ihor.malaniuk/how-to-count-documents-in-google-cloud-firestore-b0e65863aeca
sumber
Kueri ini akan menghasilkan jumlah dokumen.
sumber
Ini menggunakan penghitungan untuk membuat ID unik numerik. Dalam penggunaan saya, saya tidak akan pernah mengurangi , bahkan ketika
document
ID diperlukan untuk dihapus.Setelah
collection
penciptaan yang membutuhkan nilai numerik yang unikappData
dengan satu dokumen,set
dengan.doc
idonly
uniqueNumericIDAmount
ke 0 difirebase firestore console
doc.data().uniqueNumericIDAmount + 1
sebagai id angka unikappData
koleksiuniqueNumericIDAmount
denganfirebase.firestore.FieldValue.increment(1)
sumber
sumber