🕌

collectionGroupを前提とする場合の注意点!!とか思ってたけど書きながらハッピーな解決した

2023/01/20に公開

指定したサブコレクションをクエリ出来るって知ってました??
(面倒なんでこれからはサブコレって言ってます)

test                     ← トップコレクション
 |--- tests       ← サブコレ

例えば、上記の感じでコレクションを作ってたとして、
サブコレを参照する場合は、毎回、
testのdocIdを指定してからサブコレ取得するみたいなノリでやってました

要はこれです

_db.collection('test').doc('testId').collection('tests').where(...).get();

いや、普通はこう思うじゃ無いですかぁ

ただ、collectionGroupというものがあるみたいで
それを使うと、毎回docIdを指定しなくても共通するサブコレでクエリができるらしいのです。
ってか、できる。

ちょっと、ワタシにほんごむずかしアルのでコードみてリカイしてね

collectionGroup
_db.collectionGroup('tests').where(...).get();

これで全てのtestsというサブコレからクエリが可能になる。
毎回、docIdを指定してクエリを発火させてたから大変だったよ。それがどんだけ楽になったか。。。

と思ってたked,,,

これは魔法だぁぁぁぁ!!!!!
とか思ってたけど、問題点があった。

それはトップコレクションのdocIdが取得できないという点。

要は、collectionGroupのサブコレのDocを取得したとしても、
トップコレクションのどのDocumentに入っているのかが分からないという難点。
これ、誰かやり方知らないです??知ってたらコーヒー奢るので教えて欲しいですmm

毎回、docIdを突っ込まないとダメな感じなんですかね??

そんな訳ないやろ

と思って、取得した中身を見てみると本当にないって感じでしたね。
下記はfunctionで試しに使ってみて、取得したデータなんだけど、
どこをみても無さそう気がする・・・

QuerySnapshot {
>    _query: Query {
>      _firestore: Firestore {
>        _settings: [Object],
>        _settingsFrozen: true,
>        _serializer: [Serializer],
>        _projectId: '見せません',
>        registeredListenersCount: 0,
>        bulkWritersCount: 0,
>        _backoffSettings: [Object],
>        _clientPool: [ClientPool]
>      },
>      _queryOptions: QueryOptions {
>        parentPath: [ResourcePath],
>        collectionId: 'tests',
>        converter: [Object],
>        allDescendants: true,
>        fieldFilters: [Array],
>        fieldOrders: [],
>        startAt: undefined,
>        endAt: undefined,
>        limit: undefined,
>        limitType: undefined,
>        offset: undefined,
>        projection: undefined,
>        kindless: false,
>        requireConsistency: true
>      },
>      _serializer: Serializer {
>        createReference: [Function],
>        createInteger: [Function],
>        allowUndefined: false
>      },
>      _allowUndefined: false
>    },
>    _readTime: Timestamp { _seconds: 1674203973, _nanoseconds: 400257000 },
>    _size: 1,
>    _materializedDocs: null,
>    _materializedChanges: null,
>    _docs: [Function],
>    _changes: [Function]
>  }

これのdocsの中身は普通にサブコレのdocって感じやし、
トップコレクションのデータは一切入って無さそうな気がする。悲しい。

(...)

と思ってたけど!!!!!!

この記事を見てたら見つけたっぽいw

ちゃんとよくよく見ると、parentPathとか書いてある!!!!笑
ちょっと書きながら興奮してル。

ついでに、Flutterのクライアントから出来るかなぁと思って色々といじってると、、、

path
query.docs[0].reference.path

ってところから、取得できたなり。。

わぁ、超嬉しいわ笑
これで問題解決。

さて、使い倒そっと。ゲロ嬉しい。ゲロゲロ。

取得したPathからちゃんとIDを取得するまで

ここから微妙に行き詰まった点としては、取得したpathが下記だったから

path
tests/035e930a-8158-4b72-a5af-a5902f734437/book_test/0tpfnmGrKSfuK8CcILPv

こっから、どうやって、035e93....を取得するのか
これに約20分ほど苦戦した。

その苦戦もあってか、案外簡単に解決。

解決コード
path.split('/')[1];

これをするだけで問題なく取得が可能だった。
このsplitを使って任意の値を入れると、それを起点にして分けてくれるらしい。

split
var path = tests/035e930a-8158-4b72-a5af-a5902f734437/book_test/0tpfnmGrKSfuK8CcILPv

String test = path.split('/');
print(test);

こいつを動かすと、、、

結果
[tests, 035e930a-8158-4b72-a5af-a5902f734437, book_test, 0tpfnmGrKSfuK8CcILPv]

こんな感じになっている。
まじすげぇな。どうなってるん。これ

Discussion