【问题标题】:How to (quickly) download huge amounts of data in Firebase?如何(快速)在 Firebase 中下载大量数据?
【发布时间】:2019-02-01 02:29:48
【问题描述】:

我正在以 33Hz 的频率向 Firestore 发送数据。这意味着随着时间的推移,会存储大量数据。

我需要能够下载这些数据。为此,我在 firebase 中创建了一个 Http 函数,它接收用户 uid、设备序列号、开始日期/时间和结束日期/时间。然后该函数测试用户是否存在以及他是否拥有该序列号。然后它查询 firestore 并将数据附加到 JSON 对象,最终作为响应发送。

但是,根据查询的时间长短,函数会超时。它确实在短期内有效。

我应该怎么做才能使功能更快?我是不是用错了工具?

[...]
const nD1 = db.collection('grind-bit').doc(req.query.serial).collection('history').where('date', '>=', startdate).where('date', '<=', enddate).get().then(snapshot => {
  snapshot.forEach(doc => {
    elem = {};
    elem.date = doc.data().date;
    elem.rms0 = doc.data().rms0;
    elem.rms1 = doc.data().rms1;
    elem.rms2 = doc.data().rms2;
    data[key].push(elem);
  });
  if(data[key].length) {
    let csv = json2csv(data[key]);
    csv = JSON.stringify(csv);
    res.set("Content-Type", "text/csv");
    return promises.push(res.status(200).send(csv));
  } else {
    return promises.push(res.status(401).send('No data has been found in this interval.'));
  }
[...]

【问题讨论】:

  • 您可能希望在代码中添加一些日志语句,以查看时间流向。 Cloud Functions 的默认超时时间为 60 秒,因此如果您经过该时间段,应该可以通过简单的日志语句找到它。
  • 我已经这样做了。时间主要花在 forEach() 期间。我也尝试增加超时,但这并没有让事情变得更快。另外,我注意到这些查询的成本很高。我正在寻找替代方案。
  • 您能深入了解“在forEach() 期间”部分吗?那里的具体说明需要时间吗?因为乍一看,这一切似乎都相当简单。另外:当它成为问题时,您在该循环中处理了多少项目?许多?数千?几十万?
  • 我错了。我查询了大约 10k 个文档(每个文档 4 个字段)。在 forEach() 期间,直到 .get() 和 0.084s 结束确实需要 7.7 秒。我希望能够获得至少 200k 个文档(或更多)。顺便说一句,谢谢你的时间。
  • 好的。因此阅读文档不会占用大部分时间。但是处理 200K 文档总是需要大量时间,并且 200K * 0.084s = 16800 秒,远远超过云函数可以运行的 60-540 秒的最长时间。因此,除非您能找到一种方法来显着加快每个文档的处理速度(似乎不太可能),否则您将不得不按照我的回答并分块处理数据。

标签: javascript firebase csv google-cloud-firestore google-cloud-functions


【解决方案1】:

如果超时是由于您尝试一次性读取/返回过多数据而导致的,您可能需要考虑限制返回的数据量。通过在查询中添加limit() 子句,您可以限制它最多返回多少数据。

const nD1 = db.collection('grind-bit').doc(req.query.serial).collection('history')
.where('date', '>=', startdate).where('date', '<=', enddate)
.limit(100)
.get().then(snapshot => {
  snapshot.forEach(doc => {
    ...

这当然意味着您可能必须多次调用 HTTP 函数以确保处理所有数据。最简单的方法是:如果您得到 100 个结果(或您指定的任何限制),请在处理完之后再试一次。

另见:

【讨论】:

  • 我已经实现了它,并且它有效。在实现时,我想到了将查询异步分成一系列较小的查询。然后必须对响应进行排序,但要快得多。谢谢你的回答!
猜你喜欢
  • 2014-03-24
  • 2021-02-16
  • 2012-12-31
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 2011-09-30
  • 1970-01-01
相关资源
最近更新 更多