Firestoreで子要素の数をカウントする方法を紹介します。SQL文で言うところの、COUNT()文でレコード件数を取得する方法の、Firestoreでのやり方です。
簡単な件数の取得方法から、件数が膨大になるコレクションの効率的なカウント方法についても紹介していきます。
スポンサーリンク
100件程度の小さいコレクションのカウント方法
コレクションの数が100件程度の場合は、クライアントサイドでカウントするのが楽です。以下のサンプルコードは、usersコレクションを取得しsize
プロパティで要素の数を取得しています。
db.collection('users').get().then(snap => {
size = snap.size // will return the collection size
});
usersコレクションの全データをクライアント側でダウンロードし、要素数をカウントしていますが、100程度のコレクションであれば、対して問題ではないでしょう。
1000件ほどの少し量が多いコレクションのカウント方法
コレクションの数が1000件程度の場合、件数をカウントする為だけに、クライアントサイドに全データをダウンロードするのは時間がかかるため、Cloud Functionでコレクションの数をカウントするサーバー側のHTTP関数を用意し、クライアント側でそれを呼び出すようにします。
Cloud Function側の関数
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore()
exports.someMethod = functions.https.onRequest((req, res) => {
db.collection("users").get().then(snap => {
res.status(200).send({length: snap.size});
});
});
クライアント側の処理
yourHttpClient.post(https://xxx.cloudfunctions.net/someMethod).toPromise().then(snap => {
size = snap.length
})
スポンサーリンク
データ数が多いコレクションのカウント方法
件数が1万を超えるような件数が多いコレクションの場合、上で紹介したCloud FunctionのHTTP関数でデータの件数を数える方法でも、全データをロードしてから件数を数えるため、処理に時間がかかってしまいます。
このような件数が多いコレクションの場合、データが登録されるタイミングで件数をカウントする方法が効率がよいと言われています。
次のサンプルコードは、 Cloud Function でusersコレクションに対する変更を監視するトリガ関数を作成し、その中で、別で用意しておいたカウント値を保存する要素(sharedコレクションのcountドキュメト)に対し、登録時はインクリメントした値、削除時はデクリメントした値を設定しています。
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore()
exports.incrementUser = functions.firestore
.document('users/{userId}')
.onWrite((change, context) => {
const FieldValue = admin.firestore.FieldValue;
if (!change.before.exists) {
// 登録時に件数をインクリメント
return db.doc("shared/count").update({user: FieldValue.increment(1)});
} else if (change.before.exists && !change.after.exists) {
// 削除時に件数をデクリメント
return db.doc("shared/count").update({user: FieldValue.increment(-1)});
}
});
まとめ
Firestoreでコレクションの要素数をカウントする方法を紹介してきました。コレクションの件数が今後増えていくことが予想される場合は、最後に紹介した方法でコレクションの数をカウントすることをオススメします。
RDBだったらCOUNT()
と書けば簡単にカウントが取れるところが、Firestoreの場合は割と工夫する必要があります。といってもRDBでも件数が膨大になるとCOUNT()
が遅くなる為、結局は工夫が必要ですが…
これとは別に、Firebase Realtime Databaseで要素数をカウントする方法は、以下の記事で紹介しています。
Firebase Databaseで要素の数をカウントする方法
こちらのページの3つ目のやり方(データ数が多いコレクションのカウント方法)を参考にしながら、コレクションの要素数をカウントすることに成功しました!!ありがとうございます!
返信削除しかし、これだと今までのデータ数がカウントされません。
例えば、users/{userId}/events/以下のコレクションに、すでに50件のドキュメントがあったとします。
新たにevent(/events以下に生成される{eventId})が追加されても、カウントは「51」では無く、「1」となります。
元のデータも含めてカウントを開始するには、どうすればよいでしょうか?
このコメントはブログの管理者によって削除されました。
返信削除