firebase-admin 提供select(fields),它允许您仅获取集合中文档的特定字段。使用select 比获取所有字段的性能更高。但是,它仅适用于firebase-admin,而firebase-admin 通常仅用于服务器端。
select可以这样使用:
select('age', 'name') // fetch the age and name fields
select() // select no fields, which is perfect if you just want a count
select 可用于 Node.js 服务器,但我不确定其他语言:
https://googleapis.dev/nodejs/firestore/latest/Query.html#select
https://googleapis.dev/nodejs/firestore/latest/CollectionReference.html#select
这是一个用 Node.js 编写的服务器端云函数,它使用 select 来计算过滤后的集合并获取所有结果文档的 ID。它是用 TS 编写的,但很容易转换为 JS。
import admin from 'firebase-admin'
// https://stackoverflow.com/questions/46554091/cloud-firestore-collection-count
// we need to use admin SDK here as select() is only available for admin
export const videoIds = async (req: any): Promise<any> => {
const id: string = req.query.id || null
const group: string = req.query.group || null
let processed: boolean = null
if (req.query.processed === 'true') processed = true
if (req.query.processed === 'false') processed = false
let q: admin.firestore.Query<admin.firestore.DocumentData> = admin.firestore().collection('videos')
if (group != null) q = q.where('group', '==', group)
if (processed != null) q = q.where('flowPlayerProcessed', '==', processed)
// select restricts returned fields such as ... select('id', 'name')
const query: admin.firestore.QuerySnapshot<admin.firestore.DocumentData> = await q.orderBy('timeCreated').select().get()
const ids: string[] = query.docs.map((doc: admin.firestore.QueryDocumentSnapshot<admin.firestore.DocumentData>) => doc.id) // ({ id: doc.id, ...doc.data() })
return {
id,
group,
processed,
idx: id == null ? null : ids.indexOf(id),
count: ids.length,
ids
}
}
对于 500 个文档的集合,云函数 HTTP 请求在 1 秒内完成,每个文档包含大量数据。性能并不惊人,但比不使用select 要好得多。通过引入客户端缓存(甚至服务器端缓存)可以提高性能。
云函数入口点如下所示:
exports.videoIds = functions.https.onRequest(async (req, res) => {
const response: any = await videoIds(req)
res.json(response)
})
HTTP 请求 URL 将是:
https://SERVER/videoIds?group=my-group&processed=true
Firebase 函数详细说明了服务器在部署时的位置。