Kaedah Firestore untuk mendapatkan dokumen rawak dalam koleksi
P粉277305212
P粉277305212 2023-10-19 11:39:22
0
2
596

Adalah penting untuk apl saya dapat memilih berbilang dokumen secara rawak daripada koleksi dalam Firebase.

Memandangkan tiada fungsi asli terbina dalam dalam Firebase (setahu saya) untuk melaksanakan pertanyaan untuk melakukan ini, pemikiran pertama saya ialah menggunakan kursor pertanyaan untuk memilih indeks permulaan dan penamat rawak, dengan mengandaikan saya mempunyai koleksi of numbers Bilangan dokumen dalam .

Pendekatan ini berfungsi, tetapi hanya dengan cara yang terhad, kerana setiap dokumen akan disampaikan secara berurutan dengan jirannya setiap kali, walau bagaimanapun, saya boleh mencapai rawak jika saya dapat memilih dokumen mengikut indeksnya dalam pertanyaan Dokumentasi koleksi induknya, tetapi masalahnya ialah saya tidak dapat mencari sebarang dokumentasi yang menerangkan cara melakukan ini, atau walaupun mungkin untuk melakukan ini.

Ini yang saya nak buat, pertimbangkan seni bina firestore berikut:

root/ posts/ docA docB docC docD

Kemudian di pihak pelanggan saya (saya berada dalam persekitaran Swift) saya ingin menulis pertanyaan yang melakukan ini:

db.collection("posts")[0, 1, 3] // would return: docA, docB, docD

Bolehkah saya melakukan sesuatu yang serupa? Sebagai alternatif, adakah terdapat cara lain untuk memilih dokumen rawak dengan cara yang sama?

Tolong bantu.

P粉277305212
P粉277305212

membalas semua (2)
P粉668113768

Menyiarkan ini untuk membantu sesiapa sahaja yang menghadapi isu ini pada masa hadapan.

Jika anda menggunakan auto-ID, anda boleh menjana auto-ID baharu dan menanyakan auto-ID yang paling hampir, seperti dalamJawapan Dan McGrath.

Saya baru-baru ini mencipta api petikan rawak yang perlu mendapatkan petikan rawak daripada koleksi firestore.
Beginilah cara saya menyelesaikan masalah ini:

var db = admin.firestore(); var quotes = db.collection("quotes"); var key = quotes.doc().id; quotes.where(admin.firestore.FieldPath.documentId(), '>=', key).limit(1).get() .then(snapshot => { if(snapshot.size > 0) { snapshot.forEach(doc => { console.log(doc.id, '=>', doc.data()); }); } else { var quote = quotes.where(admin.firestore.FieldPath.documentId(), '<', key).limit(1).get() .then(snapshot => { snapshot.forEach(doc => { console.log(doc.id, '=>', doc.data()); }); }) .catch(err => { console.log('Error getting documents', err); }); } }) .catch(err => { console.log('Error getting documents', err); });

Kunci kepada pertanyaan adalah ini:

.where(admin.firestore.FieldPath.documentId(), '>', key)

Jika tiada dokumen ditemui, hubungi semula dengan operasi yang bertentangan.

Semoga ini membantu!

    P粉985686557

    Menggunakan indeks yang dijana secara rawak dan pertanyaan mudah, anda boleh memilih dokumen secara rawak daripada kumpulan koleksi atau koleksi dalam Cloud Firestore.

    Jawapan ini terbahagi kepada 4 bahagian, setiap satu dengan pilihan yang berbeza:

    1. Bagaimana untuk menjana indeks rawak
    2. Bagaimana untuk menanyakan indeks rawak
    3. Pilih berbilang dokumen rawak
    4. Reseed untuk rawak yang konsisten

    Bagaimana untuk menjana indeks rawak

    Asas jawapan ini adalah untuk mencipta medan indeks yang, apabila diisih dalam susunan menaik atau menurun, akan menyebabkan semua dokumen diisih secara rawak. Terdapat beberapa cara yang berbeza untuk mencipta ini, jadi mari kita lihat 2, bermula dengan kaedah yang paling mudah diakses.

    Mengenal versi secara automatik

    Jika anda menggunakan ID automatik yang dijana secara rawak yang disediakan dalam pustaka pelanggan kami, anda boleh menggunakan sistem yang sama untuk memilih dokumen secara rawak. Dalam kes ini, indeks yang dipesan secara rawakialahID dokumen.

    Kemudian dalam bahagian pertanyaan kami, nilai rawak yang anda hasilkan ialah ID automatik baharu (iOS,Android,Web), medan yang anda tanya ialah medan__name__dan nilai rendah 'disebut kemudian' ialah rentetan kosong. Ini adalah cara paling mudah untuk menjana indeks rawak, dan akan berfungsi tanpa mengira bahasa dan platform.

    Secara lalai, nama dokumen (__name__) 仅按升序索引,并且除了删除和重新创建之外,您也无法重命名现有文档。如果您需要其中任何一个,您仍然可以使用此方法,只需将自动 ID 存储为名为random) hanya diindeks dalam tertib menaik, dan anda juga tidak boleh menamakan semula dokumen sedia ada kecuali dengan memadam dan menciptanya semula. Jika anda memerlukan salah satu daripada ini, anda masih boleh menggunakan kaedah ini, hanya simpan ID automatik sebagai medan sebenar bernama

    dan bukannya membebankan nama dokumen untuk tujuan ini.

    Versi integer rawak

    randomApabila anda menulis dokumen, mula-mula jana integer rawak dalam julat terhad dan tetapkannya pada medan bernama

    . Bergantung pada bilangan dokumen yang anda jangkakan, anda boleh menggunakan julat sempadan yang berbeza untuk menjimatkan ruang atau mengurangkan risiko konflik (yang mengurangkan keberkesanan teknik ini).

    Anda harus mempertimbangkan bahasa yang anda perlukan kerana akan ada pertimbangan yang berbeza. Walaupun Swift mudah, JavaScript mempunyai masalah yang ketara:
    • integer 32-bit: sesuai untuk set data kecil (~10Ktidak mungkin berlanggar)
    • integer 64-bit: set data besar (nota: tidak disokong oleh JavaScript itu sendiri,belum)

    Ini akan membuat indeks dengan dokumen diisih secara rawak. Kemudian dalam bahagian pertanyaan kami, nilai rawak yang anda hasilkan akan menjadi satu lagi daripada nilai ini dan "nilai rendah" yang disebut kemudian ialah -1.

    Bagaimana untuk menanyakan indeks rawak

    Sekarang anda mempunyai indeks rawak, anda perlu menanyakannya. Di bawah ini kita melihat beberapa variasi mudah yang memilih 1 dokumen rawak, serta pilihan untuk memilih berbilang 1 dokumen.

    Untuk semua pilihan ini, anda perlu menjana nilai rawak baharu dalam bentuk yang sama seperti nilai indeks yang anda buat semasa menulis dokumen, diwakili oleh pembolehubahrandomdi bawah. Kami akan menggunakan nilai ini untuk mencari titik rawak pada indeks.

    Sarung

    Sekarang anda mempunyai nilai rawak, anda boleh menanyakan dokumen individu:

    let postsRef = db.collection("posts") queryRef = postsRef.whereField("random", isGreaterThanOrEqualTo: random) .order(by: "random") .limit(to: 1)

    Semak sama ada dokumen telah dikembalikan. Jika tidak, tanya semula, tetapi dengan "nilai rendah" indeks rawak. Contohnya, jika anda melakukan integer rawak, makalowValue0:

    let postsRef = db.collection("posts") queryRef = postsRef.whereField("random", isGreaterThanOrEqualTo: lowValue) .order(by: "random") .limit(to: 1)

    Selagi anda mempunyai satu dokumen, anda dijamin akan memulangkan sekurang-kurangnya 1 dokumen.

    Kedua-dua arah

    Kaedah balut mudah dilaksanakan dan membolehkan anda mengoptimumkan storan dengan hanya pengindeksan menaik didayakan. Satu kelemahan ialah nilai mungkin dilindungi secara tidak adil. Sebagai contoh, jika 3 dokumen pertama dalam 10K (A, B, C) mempunyai nilai indeks rawak A:409496, B:436496, C:818992, maka peluang A dan C dipilih adalah kurang daripada 1/10K , manakala B akan dipilih kerana A terlindung dengan berkesan dari jarak dekat, dan hanya mempunyai kira-kira 1/160K peluang.

    Anda boleh memilih secara rawak antara>=Daripada membuat pertanyaan sehala dan membungkus apabila nilai tidak ditemui, ini mengurangkan kebarangkalian menutup nilai secara tidak adil sebanyak separuh dengan kos menggandakan storan indeks.

    Jika tiada hasil dikembalikan ke satu arah, tukar ke arah lain:

    queryRef = postsRef.whereField("random", isLessThanOrEqualTo: random) .order(by: "random", descending: true) .limit(to: 1) queryRef = postsRef.whereField("random", isGreaterThanOrEqualTo: random) .order(by: "random") .limit(to: 1)

    Pilih berbilang dokumen rawak

    Biasanya, anda perlu memilih berbilang dokumen rawak sekaligus. Terdapat dua cara berbeza untuk menyesuaikan teknik di atas bergantung pada pertukaran yang anda inginkan.

    Bilas dan ulang

    Kaedah ini sangat mudah. Hanya ulangi proses, termasuk memilih integer rawak baharu setiap kali.

    Kaedah ini akan memberikan anda urutan rawak dokumen tanpa perlu risau melihat corak yang sama berulang kali.

    Pertukarannya ialah ia akan menjadi lebih perlahan daripada kaedah seterusnya kerana ia memerlukan perjalanan pergi balik yang berasingan untuk menyampaikan setiap dokumen.

    Teruskan

    Dalam kaedah ini, hanya menambah had bilangan dokumen yang diperlukan. Ini agak rumit kerana anda mungkin memulangkan0..limitdokumen dalam panggilan. Kemudian anda perlu mendapatkan dokumen yang hilang dengan cara yang sama, tetapi dengan batasan dikurangkan kepada hanya perbezaan. Jika anda tahu bahawa jumlah dokumen adalah lebih daripada yang anda minta, anda boleh mengoptimumkan dengan mengabaikan kes tepi di mana dokumen yang mencukupi tidak pernah diambil pada panggilan kedua (tetapi bukan yang pertama).

    Pertukaran dengan penyelesaian ini ialah urutan berulang. Walaupun dokumen diisih secara rawak, jika anda mempunyai julat bertindih, anda akan melihat corak yang sama yang anda lihat sebelum ini. Terdapat cara untuk mengurangkan kebimbangan ini, yang akan kita bincangkan dalam bahagian seterusnya mengenai pembenihan semula.

    Kaedah ini lebih pantas daripada "bilas dan ulangi" kerana anda akan meminta semua dokumen dalam satu panggilan dalam kes terbaik atau dua panggilan dalam kes terburuk.

    Reseed untuk rawak yang konsisten

    Walaupun kaedah ini akan memberikan anda dokumen secara rawak jika set dokumen adalah statik, kebarangkalian untuk mengembalikan setiap dokumen juga akan menjadi statik. Ini adalah masalah kerana sesetengah nilai mungkin mempunyai kebarangkalian yang sangat rendah atau tinggi bergantung pada nilai rawak awal yang diperoleh daripadanya. Dalam banyak kes penggunaan, ini baik, tetapi dalam sesetengahnya anda mungkin ingin meningkatkan kerawak jangka panjang supaya terdapat peluang yang lebih genap untuk mana-mana 1 dokumen dikembalikan.

    Perhatikan bahawa dokumen yang dimasukkan akhirnya saling berkait di tengah, mengubah kebarangkalian secara beransur-ansur, dan perkara yang sama berlaku untuk dokumen yang dipadamkan. Jika kadar pemasukan/pemadaman terlalu kecil untuk bilangan dokumen tertentu, terdapat beberapa strategi untuk menyelesaikan masalah ini.

    Rawak berbilang

    Anda tidak perlu risau tentang pembenihan semula, anda sentiasa boleh membuat berbilang indeks rawak setiap dokumen dan memilih salah satu daripadanya secara rawak setiap kali. Contohnya, biarkan medanrandommenjadi peta yang mengandungi subbidang 1 hingga 3:

    {'random': {'1': 32456, '2':3904515723, '3': 766958445}}

    Kini anda secara rawak akan bertanya secara rawak.1, rawak.2, rawak.3, mewujudkan taburan rawak yang lebih besar. Ini pada asasnya menggunakan ruang storan yang lebih besar untuk menjimatkan pengiraan yang meningkat (penulisan dokumen) pembenihan semula.

    Reseed sambil menulis

    Setiap kali dokumen dikemas kini, nilai rawak untuk medanrandomakan dijana semula. Ini akan mengalihkan dokumen dalam indeks rawak.

    Menyemai semula semasa dibaca

    Jika nilai rawak yang dijana tidak diagihkan secara sama rata (ia adalah rawak, jadi ini dijangka), dokumen yang sama boleh dipilih pada masa yang tidak sesuai. Masalah ini boleh diselesaikan dengan mudah dengan mengemas kini dokumen yang dipilih secara rawak dengan nilai rawak baharu selepas membacanya.

    Memandangkan penulisan lebih mahal dan boleh menjadi tempat liputan, anda boleh memilih untuk mengemas kini hanya pada subset masa baca (cth.if random(0,100) === 0) update;).

      Muat turun terkini
      Lagi>
      kesan web
      Kod sumber laman web
      Bahan laman web
      Templat hujung hadapan
      Tentang kita Penafian Sitemap
      Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!