Firestoreでselect()を使って特定のフィールドのみ取得する
Firebase Advent Calendar 2019 の18日目です。17日目はlaisoさんの「Cloud FunctionsをGoで書く。またはFirebaseのためのマイクロサービスアーキテクチャ」でした。
今日はFirestoreでselect()を使って、Documentまるごとではなく、特定のフィールドの値のみを取得する方法についてです。 Document内にMapやArrayでそれなりのデータ量を持つことはしばしばあり、また表示側ではそれらは使用しないケースなども多いため、また転送量を節約するために必要なフィールドのみを取得したいということはよくあるニーズかと思います。
RDBMS慣れしている方からするとなにを当たり前のことを、って思われるかもしれませんが、2019-12-17現在Firebaseの firebase-js-sdk
及び Firestore APIでは select()
相当の機能は提供されていません。
つまり、必然的にDocument内の全データを取得することになります。
ではどうすれば良いのかというと、実はGCP側のFirestoreには .select()
のAPIが提供されていて、StructuredQueryを使って取得することができました。
いつの間にか @google-cloud/firestore
のSDKにも .select() のメソッドが追加されていたので、それを使って取得します。
CollectionReference - Documentation
データ例
実装
const snapshot = await firestore .collection('posts') .where('field1', '==', 'value1') .select('title', 'body') .get(); const doc = snapshot.docs[0]; const data = doc.data(); console.dir(data);
上記のコード例の場合、field1 が value1
という値の、 title
body
フィールドの値のみを取得します。
.select() を使用せずにsnapshotからDocumentを取得した場合、Document内の全フィールドが取得されますが、.select() を指定することにより指定したフィールドの値のみで取得することができます。
お気づきかとは思いますがこの方法の一番デメリットとして、 @google-cloud/firestore
を使う必要があります。
普通にFirebaseを使っている場合は firebase-js-sdk
firebase-admin-node
を使用しているケースが多いかと思うので、それらと併用することになります。
select()するためだけにGCP側のSDKから毎回引っ張ってくるのも煩雑だし、FirebaseとGCPのFirestore SDK混在したくないというのもあるので、現時点でどうしてもselect()したい時に使える選択肢の1つとして考えておくのが良いかと思います。
明日は @tomoeine さんです、お楽しみに!