Menggunakan API Kueri Firebase , Anda mungkin tergoda untuk mencoba ini:
// !!! THIS WILL NOT WORK !!!
ref
.orderBy('genre')
.startAt('comedy').endAt('comedy')
.orderBy('lead') // !!! THIS LINE WILL RAISE AN ERROR !!!
.startAt('Jack Nicholson').endAt('Jack Nicholson')
.on('value', function(snapshot) {
console.log(snapshot.val());
});
Tetapi seperti yang dikatakan @RobDiMarco dari Firebase dalam komentar:
beberapa orderBy()
panggilan akan menimbulkan kesalahan
Jadi kode saya di atas tidak akan berfungsi .
Saya tahu tiga pendekatan yang akan berhasil.
1. filter paling banyak di server, lakukan sisanya pada klien
Yang dapat Anda lakukan adalah menjalankan satu orderBy().startAt()./endAt()
di server, tarik ke bawah data yang tersisa dan filter itu dalam kode JavaScript pada klien Anda.
ref
.orderBy('genre')
.equalTo('comedy')
.on('child_added', function(snapshot) {
var movie = snapshot.val();
if (movie.lead == 'Jack Nicholson') {
console.log(movie);
}
});
2. tambahkan properti yang menggabungkan nilai yang ingin Anda filter
Jika itu tidak cukup baik, Anda harus mempertimbangkan memodifikasi / memperluas data Anda untuk memungkinkan kasus penggunaan Anda. Misalnya: Anda bisa memasukkan genre + lead ke satu properti yang baru saja Anda gunakan untuk filter ini.
"movie1": {
"genre": "comedy",
"name": "As good as it gets",
"lead": "Jack Nicholson",
"genre_lead": "comedy_Jack Nicholson"
},...
Anda pada dasarnya membangun indeks multi-kolom Anda sendiri dengan cara itu dan dapat menanyakannya dengan:
ref
.orderBy('genre_lead')
.equalTo('comedy_Jack Nicholson')
.on('child_added', function(snapshot) {
var movie = snapshot.val();
console.log(movie);
});
David East telah menulis perpustakaan bernama QueryBase yang membantu menghasilkan properti seperti itu .
Anda bahkan dapat melakukan kueri / rentang relatif, katakanlah Anda ingin mengizinkan kueri film berdasarkan kategori dan tahun. Anda akan menggunakan struktur data ini:
"movie1": {
"genre": "comedy",
"name": "As good as it gets",
"lead": "Jack Nicholson",
"genre_year": "comedy_1997"
},...
Dan kemudian mencari komedi tahun 90-an dengan:
ref
.orderBy('genre_year')
.startAt('comedy_1990')
.endAt('comedy_2000')
.on('child_added', function(snapshot) {
var movie = snapshot.val();
console.log(movie);
});
Jika Anda perlu memfilter lebih dari sekedar tahun, pastikan untuk menambahkan bagian tanggal lainnya dalam urutan menurun, misalnya "comedy_1997-12-25"
. Dengan cara ini urutan leksikografis yang dilakukan Firebase pada nilai string akan sama dengan urutan kronologisnya.
Menggabungkan nilai-nilai dalam properti dapat bekerja dengan lebih dari dua nilai, tetapi Anda hanya bisa melakukan filter rentang pada nilai terakhir di properti komposit.
Varian yang sangat istimewa ini diterapkan oleh perpustakaan GeoFire untuk Firebase . Perpustakaan ini menggabungkan garis lintang dan garis bujur dari suatu lokasi ke dalam apa yang disebut Geohash , yang kemudian dapat digunakan untuk melakukan kueri rentang waktu nyata di Firebase.
3. buat indeks kustom secara terprogram
Namun alternatif lain adalah melakukan apa yang kita semua lakukan sebelum API Kueri baru ini ditambahkan: buat indeks di simpul yang berbeda:
"movies"
// the same structure you have today
"by_genre"
"comedy"
"by_lead"
"Jack Nicholson"
"movie1"
"Jim Carrey"
"movie3"
"Horror"
"by_lead"
"Jack Nicholson"
"movie2"
Mungkin ada lebih banyak pendekatan. Misalnya, jawaban ini menyoroti indeks kustom berbentuk pohon alternatif: https://stackoverflow.com/a/34105063
orderBy()
panggilan akan menimbulkan kesalahan, karena klien saat ini memberikan hasil yang tidak terduga. Mungkin saja tes ini bekerja secara kebetulan, tetapi tidak dibuat untuk bekerja secara umum (meskipun kami ingin menambahkannya!)..equalTo('comedy')
bukan.startAt('comedy').endAt('comedy')
?Saya telah menulis perpustakaan pribadi yang memungkinkan Anda memesan dengan beberapa nilai, dengan semua pemesanan dilakukan di server.
Temui Querybase!
Querybase menggunakan Referensi Firebase Database dan berbagai bidang yang ingin Anda indeks. Saat Anda membuat catatan baru, itu akan secara otomatis menangani pembuatan kunci yang memungkinkan untuk beberapa permintaan. Peringatannya adalah ia hanya mendukung kesetaraan lurus (tidak kurang dari atau lebih besar dari).
sumber
sumber
Jawaban Frank bagus tetapi Firestore
array-contains
baru-baru ini memperkenalkannya yang membuatnya lebih mudah dilakukan DAN pertanyaan.Anda dapat membuat
filters
bidang untuk menambahkan Anda filter. Anda dapat menambahkan nilai sebanyak yang Anda butuhkan. Misalnya untuk memfilter menurut komedi dan Jack Nicholson Anda dapat menambahkan nilaicomedy_Jack Nicholson
tetapi jika Anda juga ingin komedi dan 2014 Anda dapat menambahkan nilaicomedy_2014
tanpa membuat lebih banyak bidang.sumber
Firebase tidak mengizinkan kueri dengan berbagai kondisi. Namun, saya memang menemukan jalan keluar untuk ini:
Kita perlu mengunduh data yang difilter awal dari database dan menyimpannya dalam daftar array.
Setelah kami mendapatkan data yang difilter awal dari database, kami perlu melakukan filter lebih lanjut di backend kami.
sumber
Ini akan bekerja
sumber