[解決済み】Firebaseで複数のwhere句に基づくクエリ
質問
{
"movies": {
"movie1": {
"genre": "comedy",
"name": "As good as it gets",
"lead": "Jack Nicholson"
},
"movie2": {
"genre": "Horror",
"name": "The Shining",
"lead": "Jack Nicholson"
},
"movie3": {
"genre": "comedy",
"name": "The Mask",
"lead": "Jim Carrey"
}
}
}
Firebase初心者です。上記のデータから結果を取り出すにはどうしたらいいでしょうか?
ここで
genre = 'comedy'
AND
lead = 'Jack Nicholson'
?
どのようなオプションがありますか?
解決方法は?
使用方法 Firebaseのクエリ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. サーバでほとんどをフィルタリングし、残りをクライアントで実行する。
何を
できる
を実行することです。
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 が文字列値に対して行う辞書的順序付けが、時系列的順序付けと同じになります。
このプロパティ内の値の結合は、2つ以上の値で動作しますが、複合プロパティの最後の値に対してのみ範囲フィルタリングを行うことができます。
これの非常に特殊なバリエーションを実装したのが Firebase用GeoFireライブラリ . このライブラリは、位置の緯度と経度を組み合わせて、いわゆる ジオハッシュ これを利用して、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
もし、これらのオプションのどれにも当てはまらないが、データをFirebaseに保存したいのであれば、Firebaseの持つ Cloud Firestoreデータベース .
Cloud Firestoreは1つのクエリで複数の等式フィルタを扱うことができますが、範囲フィルタは1つだけです。ボンネットの中では基本的に同じクエリモデルを使いますが、複合プロパティを自動生成してくれるようなものです。Firestoreのドキュメントを参照してください。 複合クエリ .
関連
-
[解決済み] FirebaseのapiKeyを公開しても大丈夫ですか?
-
[解決済み] Firebaseでアプリがバックグラウンドにあるときの通知を処理する方法
-
[解決済み] Cloud FirestoreとFirebase Realtime Databaseの違いとは?
-
[解決済み】Firebaseのdevとprodの環境を分ける。
-
[解決済み] Firebaseメッセージング、Server Keyはどこで入手できますか?
-
[解決済み] Firebaseアプリにコラボレーターを追加する方法とは?
-
[解決済み] HTTPエラー。401 android プロジェクトで firebase cloud の機能を設定する際に発生するエラー。
-
[解決済み] 他の関数に影響を与えずに、いくつかの関数をCloud Functions for Firebaseにデプロイするには?
-
[解決済み] firebase cliからアプリを切り替えるには?
-
[解決済み] Java修飾語(abstract, final, public, static, etc.)の妥当な順番は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Firebase v3 updateProfile メソッド
-
[解決済み] エラーです。Objective-Cモジュール'Firebase'をビルドできませんでした。
-
[解決済み] エラーで終了しました。Gradle タスク assembleDebug は終了コード 1 で失敗しました。
-
[解決済み] Firebase Cloud MessagingのAPI KEYはどこにありますか?
-
[解決済み] アプリを別のFirebaseアカウントに転送する
-
[解決済み] Firebaseアプリにコラボレーターを追加する方法とは?
-
[解決済み] タイプ 'List<dynamic>' はタイプ 'List<Widget>' のサブタイプではありません。
-
[解決済み] どうしたら解決できますか?Error: Firebase プロジェクトのリストアップに失敗しました。詳細はfirebase-debug.logを参照してください。
-
[解決済み] Google Firestoreです。プロパティ値の部分文字列に対するクエリ (テキスト検索)
-
[解決済み] Firebaseストレージとアクセス制御・許可・オリジン