uwu

プログラミングの備忘録を書いています。誰かの為になれば幸いです

Firestore Cloud firestoreの公式動画まとめ2

前回の記事の続きになります。


www.youtube.com
※この記事で使われている全ての画像はこの動画内から切り抜いたものです。



今回の動画では、
「クエリがどのように働くのか」
について詳しく説明してくれています。
では早速見ていきましょう!



DBからデータを取得する際、クエリと呼ばれるものを使います。



クエリを使ってデータを取得する時は、一つのコレクション
またはサブコレクションのドキュメントしか取得できません。


これはどういう意味か、
前回の動画同様レストランのレビューアプリのDBを例として見ていきます。



「レストランコレクション」の中に「レビューサブコレクション」があります。
レストランコレクションにはレストランの郵便番号などの情報が格納されているとします。
レビューサブコレクションにはレストランの評価が格納されているとします。







このようなDB構成の場合、「郵便番号ドキュメント」を指定して
その郵便番号と同じ場所にあるレストランを見つけることができます。



他にも、特定のレストランの4スターがついたレビューを取得したい場合、
「レストラン」コレクションの中にあるサブコレクションの、「レビュー」の中の
「評価」ドキュメントを指定することでデータを見つけることができます。



しかし、全てのレストランから4スターのレビューを取得することはできません。
複数のサブコレクションをまたがることになるからです。




2019年からできるようになった!

2019年から「コレクショングループクエリ」を
使用することでできるようになりました。



コレクショングループはFirestoreのコンソールから
どのフィールドを、どのコレクションから検索したいかを指定することで使用できます。





コレクショングループクエリには注意したいことが2つあります。


1.2019年時点では、インデックスは200個までという制限がある


端的に言うと、コレクショングループ=インデックスです。



2.コレクショングループクエリは同じ名前の全てのコレクションを探しにいく



つまり、もし同じ名前のサブコレクションが
別のコレクションに存在する場合、そのサブコレクションも含まれるということです。


インデックスの種類について:
Cloud Firestore のインデックスの種類  |  Firebase



クエリのルール


・実行するクエリは等価比較、大小比較を元に作成するべきである



どういうことかまたレストランのレビューアプリのDBを想定して説明します。



例えば、サンフランシスコにあるすべてのレストランを取得したい場合、
name = "San Francisco"
評価が星4以上あるすべてのレストランを取得したい場合
rating => 4
のような感じです。クエリに計算式を含めることはできません。



・クエリを実行するのに掛かる時間は、取得される結果の数に比例する


ある郵便番号でその地域にあるすべてのレストランを取得したい場合、レストランが
60件であっても60万件であっても600万件であってもクエリにかかる時間は一緒です。



なぜそのようなことが可能なのか??




Firestoreではドキュメントを追加する時に
ドキュメントの全てのフィールド、マップに自動的にインデックスを貼ります。
インデックスとは辞書でいう索引みたいなものです。




マップとは、以下のJSONみたいなフィールドのことです




上の例の場合、address.zipのインデックスが作成されます。
このインデックスがクエリを早くするポイントです。



クエリでできないこと

テキスト検索ができません。
フルテキスト検索のような検索をしたい場合、サードパーティを使う必要があります。



以下のようなORも使うことができません。
name = "italian" || name = "french"



ORは二つのクエリを使って得た情報を合体させることで実現できます。
name = "italian"
name="french"
また、DBを見直すこともできます。
例えば、イタリアンとフレンチに共通するヨーロッパ料理というフィールドを作り
true/falseで判定するといったこともできます。



!=も使用できません。


NoSQLは値に決まったデータ型を入れる必要がありませんが、
違うデータ型を値に入れることを推奨しません。




画僧のように評価を数値と、文字列で入れてしまった場合、
数値に対するクエリと文字列に対するクエリの2つを使わなければならなくなるからです。


複合クエリについて

例えば、サンフランシスコにある全ての日本食レストランでファミリー向けのレストランのデータを取得したいとします。
Cuisine = "Japanese"
City = "San Francisco"
KidFriendly = true



こういった全てが等価評価「=」で取得できるクエリなら問題ありません。



例えば、郵便番号○○番のエリアにある星4以上のレストランという条件で検索をする場合、Rating => 4という大小評価で取得しなければならないため勝手が変わります。




この問題をFirebase Real-time databaseではこのようにドキュメントに
「zipcode_rating:94045_4.76 」を追加することで解決します。





この複合されたフィールドが変更されるたびに更新をしたりと管理するのは大変です。
そこで、Firestoreでは複合クエリ(composite indexes)というものを使います。


複合クエリは自動的に複合したフィールドを作成し、値が変わるたびに自動で更新をしてくれます。



複合クエリはFirestoreのコンソールから作れるほか
複合クエリが必要なクエリを実行するとエラーを返してくれそのエラーに乗っているURLをクリックして作成することができます。(推奨)


複合クエリの詳細

・大小評価をするクエリは一番最後に持ってくるのがおすすめ
・大小評価をする2つのクエリを複合クエリにすることはできない

例)
rating >= 4.0
noise >= 3

noise_raitng >= ??? ←できない

rating >= 4.0
sort by rating
sort by noise

rating_noise >= 4.0 ←できる



3へ続きます。