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!).