【发布时间】:2020-03-18 12:37:30
【问题描述】:
谁能帮我解决 Firestore 中的聚合查询。 似乎 Firestore 是关于限制和限制的。
我有两个集合,我需要使用.limit()过滤来抓取一定数量的用户,然后我需要在另一个集合中查找对应的记录。
我使用where in 过滤器进行的第二个查询,但显然我在where in 过滤器的查询数组中只能有10 个项目。
我设法处理此请求的唯一方法是:
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 的批量数组
- 制作请求列表并分配一个包含 10 个 ID 的数组(显然这不是一个好主意,我想避免它。我必须向 Firestore DB 发出许多请求)
-
Promise.all我履行所有承诺 - 过滤和排序结果准备输出数据
如果有任何帮助,我将不胜感激
提前致谢!
【问题讨论】:
-
这是您第三次尝试提出同样的问题,虽然我可以看到您试图集中问题,但我仍然不明白您在问什么。如果我发布类似“是的,Firestore 上的聚合查询很难”之类的答案,那会是您正在寻找的答案吗?还是您发布的代码有问题?如果是这样,哪条线没有做你想做的事?如果您在帖子中写一个具体且重点突出的问题,这真的很有帮助。
-
Firestore 是关于速度和可扩展性的。为了实现这些,需要限制。为了充分利用 Firestore,我建议学习如何欣赏其优势并解决其局限性。 medium.com/firebase-developers/…
-
@FrankvanPuffelen 感谢您的回答!是的,这是我第二次尝试找出如何克服 Firestore 中的聚合限制。对于这个简单的任务,我必须建立 4 个数据库连接,但只有 2 个。是的,我完全同意可能存在一些限制,但我编写的代码在我看来太错误了。这就是为什么我阅读了大量的官方文档和文章,但无论如何只有限制.. 上面的代码是我试图从 Firebase 获取数据的方式 - 发出许多数据库请求,在准备查询时为不可预测的错误添加了一个位置?
-
@FrankvanPuffelen 这就是我感兴趣的……在我看来,我的代码使用起来很糟糕。我以为我做错了什么。所以我想听听有经验的人如何应对 Firestore 中的聚合。
-
好的或坏的做法是一种意见,Stack Overflow 不适合。但客观地说,Firestore 可能不是运行临时聚合的最佳数据库。如果您需要进行临时聚合,您可能最好使用更适合此的数据库,例如 BigQuery,它擅长对任意大型数据集进行临时聚合查询。如果您想坚持使用 Firestore,请考虑预先聚合数据,这意味着您将聚合存储到数据库本身,并在每次相关的写入操作时更新它们。
标签: node.js firebase google-cloud-firestore google-cloud-functions