FirestoreのCollection Group Queries(コレクショングループクエリ)について


これは何

ここに説明が書いてありますが、例が個人的には分かりずらかったので、なんなのかを一言で説明すると、

同じ名前のサブコレクションに対してデータベース全体を跨ってクエリが書ける機能 です。

終わり

簡単な例

以下のようなpiyoサブコレクションがあったとします。
/hoge/{hogeId}/piyo
/hogehoge/{hogehogeId}/piyo
/foo/{fooId}/bar/{barId}/piyo

以下のように書くことで全てのpiyoサブコレクションからtypeフィールドが'fuga'のドキュメントを検索できます。
親のコレクション名や階層が違ってもOK。

db.collectionGroup('piyo').where('type', '==', 'fuga');

ただし、以下のようなセキュリティルールを書いておく必要があります。

match /{path==**}/piyo/{piyoId} {
  allow read: if true
}

いやいや、そんなルール書いたら見られちゃいけないものまで全部見れちゃうやんけ!!
それがまずい場合、フィールドの内容で制限がかけられます。

publicフィールドがtrueのもののみアクセス可能
match /{path==**}/piyo/{piyoId} {
  allow read: if resource.data.public;
}

ただし、上記のようにフィルタリングする場合は、条件以外のドキュメントにアクセスしないようにクエリでもその条件で絞ってあげる必要があります。

db.collectionGroup('piyo').where('public', '==', true);

ユーザーIDで絞る場合も、ユーザーIDをドキュメント内に格納しておくことで可能です。

match /{path==**}/piyo/{piyoId} {
  allow read: if resource.data.user == request.auth.uid;
}

もちろんクエリでも指定する必要があります。

db.collectionGroup('piyoSubCollection').where('user', '==', uid);

ドキュメントパスで絞りたいんだけど…
多分、無理っぽいです。

公式のドキュメントにそれっぽい説明がありますが、書いてあることが私には意味不明です。
この文章の意味がわかる方がいたら是非教えてください。