【发布时间】:2022-04-01 17:02:49
【问题描述】:
我的 Firebase 实时数据库中有超过 20k 个对象。我现在需要取出所有这些对象并对它们进行处理。问题是每次我这样做时服务器都会耗尽内存。这是我当前的代码:
sendEmail.get('/:types/:message', cors(), async (req, res, next) => {
console.log(5);
const types = JSON.parse(req.params.types);
console.log('types', types);
let recipients = [];
let mails = [];
if (types.includes('students')) {
console.log(1);
const tmpUsers = await admin.database().ref('Users').orderByChild('student').equalTo(true).once('value').then(r => r.val()).catch(e => console.log(e));
recipients = recipients.concat(tmpUsers);
}
if (types.includes('solvers')) {
console.log(2);
let tmpUsers = await admin.database().ref('Users').orderByChild('userType').equalTo('person').once('value').then(r => r.val()).catch(e => console.log(e));
tmpUsers = tmpUsers.concat(arrayFromObject(await admin.database().ref('Users').orderByChild('userType').equalTo('company').once('value').then(r => r.val()).catch(e => console.log(e))));
recipients = recipients.concat(tmpUsers);
}
});
所以我有两个选择。使用startAt 和endAt 流式传输或限制响应。但是为了限制响应,我需要知道我到底有多少对象。要做到这一点,我需要下载整个集合......你现在看到我的问题了。如何在不下载整个集合的情况下了解我有多少文档?
【问题讨论】:
-
诀窍是使用
limitToFirst/limitToLast结合startAt/endAt。例如,您可以使用limitToFirst(100)执行第一个查询,然后从返回的列表中获取最后一个键并将其用于:startAt(key)和另一个limitToFirst(100)。在讨论range queries 的文档中有一个简单的示例,它暗示了这一点。我看看能不能写一个 node.js 的例子。 -
我很感激一个例子。我想我明白你的意图,但我不确定我是否完全理解
-
我会尝试制作一个。不过再想一想:如果是 Cloud Function 在处理大型数据集时超时,您可以改为 increase the function's timeout and memory allocation。
-
我已经试过了。 2GB是不够的。我自己都震惊了
-
实际上我不确定分页是否会有所帮助,因为我已经编写了一个示例。无论如何我都会发布我的答案,但您可能不得不将数据处理拆分为多个函数调用。
标签: javascript node.js firebase firebase-realtime-database