首页 > 解决方案 > 在 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);

}

  1. 我拿用户列表
  2. 获取他们的 id 并制作包含多达 10 个 id 的批量数组
  3. 制作请求列表并分配一个包含十个 id 的数组(显然这不是一个好主意,我想避免它。我必须向 Firestore DB 发出许多请求)
  4. 通过Promise.all我履行我所有的承诺
  5. 过滤和排序结果准备输出数据

我会很感激这里的任何帮助

提前致谢!

标签: node.jsfirebasegoogle-cloud-firestoregoogle-cloud-functions

解决方案


如果您需要运行大量临时聚合,那么 Firestore 可能不是最适合您的数据库。在这种情况下,您可能最好使用更适合临时查询的数据库,例如 BigQuery,它擅长对任意大型数据集进行此类聚合查询。

如果您想坚持使用 Firestore,请考虑预先聚合数据,这意味着您将聚合存储到数据库本身,并在每次相关的写入操作时更新它们。这意味着您将无法再临时执行它们,并且您的写入操作变得更加复杂,但好在检索聚合信息将变得非常简单。

这是您将在 NoSQL 数据库中看到的常见权衡:您需要为您的用例定制数据结构,并且通常会权衡读/写可扩展性和成本。

这个话题已经出现了几次,所以也可以看看:


推荐阅读