FirebaseのQuery APIを使用すると、これを試してみたくなるかもしれません。
// !!! 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());
});
しかし、Firebaseの@RobDiMarcoがコメントで言っているように:
複数のorderBy()
呼び出しはエラーをスローします
したがって、上記の私のコードは機能しません。
うまくいく3つのアプローチを知っています。
1.サーバーで大部分をフィルタリングし、残りをクライアントで行います
あなたがすることができません、1つを実行しているorderBy().startAt()./endAt()
クライアント上のJavaScriptコードであること、サーバー上に残っているデータとフィルタプルダウン。
ref
.orderBy('genre')
.equalTo('comedy')
.on('child_added', function(snapshot) {
var movie = snapshot.val();
if (movie.lead == 'Jack Nicholson') {
console.log(movie);
}
});
2.フィルタリングする値を組み合わせるプロパティを追加します
それでも不十分な場合は、ユースケースを許可するようにデータを変更または拡張することを検討してください。たとえば、このフィルターに使用する単一のプロパティにジャンル+リードを含めることができます。
"movie1": {
"genre": "comedy",
"name": "As good as it gets",
"lead": "Jack Nicholson",
"genre_lead": "comedy_Jack Nicholson"
},...
あなたは本質的にあなた自身のマルチカラムインデックスをそのように構築していて、それでクエリすることができます:
ref
.orderBy('genre_lead')
.equalTo('comedy_Jack Nicholson')
.on('child_added', function(snapshot) {
var movie = snapshot.val();
console.log(movie);
});
David Eastは、このようなプロパティの生成に役立つQueryBaseと呼ばれるライブラリを作成しました。
相対/範囲クエリを実行することもできます。たとえば、カテゴリと年で映画のクエリを許可するとします。次のデータ構造を使用します。
"movie1": {
"genre": "comedy",
"name": "As good as it gets",
"lead": "Jack Nicholson",
"genre_year": "comedy_1997"
},...
次に、90年代のコメディをクエリします。
ref
.orderBy('genre_year')
.startAt('comedy_1990')
.endAt('comedy_2000')
.on('child_added', function(snapshot) {
var movie = snapshot.val();
console.log(movie);
});
年だけでなくフィルタリングする必要がある場合は、他の日付部分を降順に追加して"comedy_1997-12-25"
ください。このように、Firebaseが文字列値に対して行う辞書式順序は、年代順と同じになります。
プロパティの値のこの組み合わせは、3つ以上の値で機能しますが、複合プロパティの最後の値に対してのみ範囲フィルターを実行できます。
これの非常に特殊なバリアントは、FirebaseのGeoFireライブラリによって実装されます。このライブラリは、場所の緯度と経度を組み合わせて、いわゆるGeohashを作成します。これを使用して、Firebaseでリアルタイムの範囲クエリを実行できます。
3.プログラムでカスタムインデックスを作成する
さらに別の方法は、この新しいQuery APIが追加される前に私たち全員が行ったことを実行することです。別のノードにインデックスを作成します。
"movies"
// the same structure you have today
"by_genre"
"comedy"
"by_lead"
"Jack Nicholson"
"movie1"
"Jim Carrey"
"movie3"
"Horror"
"by_lead"
"Jack Nicholson"
"movie2"
おそらくもっと多くのアプローチがあります。たとえば、この回答は別のツリー型のカスタムインデックスを強調しています:https : //stackoverflow.com/a/34105063
orderBy()
れると、クライアントが現在予期しない結果を返すため、複数の呼び出しはエラーをスローします。テストで偶然機能した可能性がありますが、これを一般的に機能するように構築されていません(追加したいのですが!)。