node.js - 在 Firebase 中处理大量数据或如何避免“在哪里”限制?
问题描述
谁能帮助我在 Firestore 中进行聚合查询。似乎 Firestore 是关于限制和限制的。
我有两个集合,我需要使用过滤来抓取一定数量的用户.limit()
,然后我需要在另一个集合中查找相应的记录。
我使用过滤器进行的第二个查询,但显然我在过滤器where in
的查询数组中只能有 10 个项目。where in
我设法处理此请求的唯一方法是:
async ({ query }: Request, res: Response) => {
const users: any = [];
const ids: any = [];
const stats: any = [];
await firestore.collection('users').limit(30).get()
.then((snapshot) => {
let i = 1;
let d: any = [];
snapshot.forEach(doc => {
users.push(doc.data());
if (i <= 9) {
d.push(doc.data().id);
i++;
} else if (i === 10) {
d.push(doc.data().id);
i = 1;
ids.push(d);
d = [];
}
});
}).catch(console.log);
const promises: any = [];
ids.forEach((tens: any, index: number) => {
if (tens) {
promises.push(firestore.collection('users_statistic').
where('user_id', 'in', ids[index])
.get()
.then((snapshot) => {
const data: any = [];
snapshot.forEach(doc => data.push(doc.data()))
return data;
}))
}
});
await Promise.all(promises).then(stat => {
stat.forEach(t => {
stats.push(...(t as []));
})
}).catch(console.log);
const sortedStats: any = {};
users.forEach((user: any) => {
sortedStats[user.id] = stats.filter((data: any) => data.user_id === user.id);
});
const totals = [];
for (const key in sortedStats) {
if (sortedStats.hasOwnProperty(key)) {
const value = sortedStats[key];
const clicks = value.reduce((acc: any, v: any) => acc + v.clicks, 0);
const views = value.reduce((acc: any, v: any) => acc + v.page_views, 0);
totals.push({
...users[key],
clicks,
views
})
}
}
res.status(200).send(totals);
}
- 我拿用户列表
- 获取他们的 id 并制作包含多达 10 个 id 的批量数组
- 制作请求列表并分配一个包含十个 id 的数组(显然这不是一个好主意,我想避免它。我必须向 Firestore DB 发出许多请求)
- 通过
Promise.all
我履行我所有的承诺 - 过滤和排序结果准备输出数据
我会很感激这里的任何帮助
提前致谢!
解决方案
如果您需要运行大量临时聚合,那么 Firestore 可能不是最适合您的数据库。在这种情况下,您可能最好使用更适合临时查询的数据库,例如 BigQuery,它擅长对任意大型数据集进行此类聚合查询。
如果您想坚持使用 Firestore,请考虑预先聚合数据,这意味着您将聚合存储到数据库本身,并在每次相关的写入操作时更新它们。这意味着您将无法再临时执行它们,并且您的写入操作变得更加复杂,但好在检索聚合信息将变得非常简单。
这是您将在 NoSQL 数据库中看到的常见权衡:您需要为您的用例定制数据结构,并且通常会权衡读/写可扩展性和成本。
这个话题已经出现了几次,所以也可以看看:
推荐阅读
- php - 嵌套foreach,如何更高效
- c# - 为什么我必须在循环中输入两次度数?
- ruby - 来自 Model.search 和 SearchKick.search 的不同结果,带有 named_index
- python - Python Regex[Forking] - 根据术语捕获组,但如果遇到集合中的另一个术语则跳过
- python - 查询实体的正则表达式
- spacy - SpaCy:从字符索引中获取令牌
- linux - 如何从 perf 报告中获取 PEBS 数据线性地址和延迟值?
- spring-boot - spring cloud config服务器-客户端刷新策略
- r - 如何通过向函数添加输出来防止重写闪亮的块?
- frama-c - 在 Frama-C 中强制执行 WP 内存模型所做的假设