Dokumen Kueri Firestore Dengan Array Serupa (Node.js / Admin SDK)

Aug 16 2020

Bayangkan Anda memiliki array ini

[10.3, 14, 12.4, 3.5]

dan di DB Anda, Anda juga memiliki dua dokumen dengan array tersebut:

First document -> [10, 13.1, 0, -10]
Second document -> [0, 0, 0, 0]

Sekarang bayangkan Anda memiliki +1000000 dokumen dengan dua larik yang sama (bergantian di antara masing-masing) ... Adakah cara untuk mendapatkan semua dokumen yang memiliki nilai serupa dengan larik Anda saat ini?

Maksud saya, sesuatu seperti ini:

   ...
   .where("array", "isSimilar", yourArray)
   .get()

Sehingga saya mendapatkan semua dokumen yang memiliki array:

[10, 13.1, 0, -10]

Atau satu-satunya cara adalah mengunduh setiap dokumen, sesuatu yang bisa sangat lambat, lalu mengulang dan mencari yang paling mirip? Saya pikir ini bisa sangat menarik ketika berbicara tentang "posisi titik yang sama", "minggu ketika pengguna kehilangan berat badan yang sama", ...

Terima kasih.

Jawaban

3 JayCodist Aug 16 2020 at 09:20

Saat ini, firestore tidak mendukung kueri semacam itu. Jadi saya sarankan Anda memperbarui struktur Anda untuk menyertakan bidang String untuk perbandingan array. Jadi setiap dokumen akan terlihat seperti ini:

{
   array: [12, 11, 8, 9],
   arrayStr: "12,11,8,9",
   ...
}

Anda dapat mencapai struktur ini hanya dengan memanggil doc.array.join(",")semua dokumen yang ada dan menyimpan nilainya ke dokumen.

Kemudian, dimungkinkan untuk membuat perbandingan dengan kueri firestore, seperti:

const arrToCompare = [12, 11, 8, 9];
const snapshot = await firestore().collection(collection).where("arrayStr", "==", arrToCompare.join(",")).get();
...

PEMBARUAN: Untuk membandingkan berdasarkan kesamaan, bukan persamaan, pendekatan yang mungkin adalah menerapkan logika "kesamaan" Anda ke arrayStrbidang selama pembuatan. Misalnya, jika Anda ingin perbedaan yang kurang dari 0,5 dapat ditoleransi, Anda dapat menggunakan Math.round()elemen array sebelum menyimpannya sebagai string. Seperti:

const array = [12.2, 10.7, 8.111, 9.0];
const arrayStr = array.map(num => Math.round(num)).join(","); //"12,11,8,9"

Kemudian Anda akan menanyakannya seperti ini:

const arrToCompare = [12, 11, 8, 9];
const snapshot = await firestore().collection(collection).where("arrayStr", "==", arrToCompare.map(num => Math.round(num)).join(",")).get();
// Results would include arrays like [12.2, 10.7, 8.111, 9.0]
...

Tentu saja, Anda dapat memvariasikan argumen yang diteruskan Math.round()untuk menambah atau mengurangi tingkat toleransi untuk perbandingan