编写这个Node.js逻辑以从Google云存储检索和更新CSV数据的更具可扩展性的方法?

编写这个Node.js逻辑以从Google云存储检索和更新CSV数据的更具可扩展性的方法?,node.js,rest,csv,google-cloud-storage,Node.js,Rest,Csv,Google Cloud Storage,我正在创建我的第一个Node.js REST API测试项目,它可以检索奖品。该逻辑旨在执行以下操作: 从与项目关联的Google云存储桶中检索CSV 解析CSV 查找未填充列“Claimed”的第一行 将“索赔”列更新为“索赔!” 覆盖Google云存储中CSV文件中的数据 返回与该行关联的奖品名称 我的逻辑目前在本地工作,但我想知道是否有更好、更可伸缩的方法来编写代码。我将以每天约10万用户的500/分钟的速率限制对其进行测试,并最终传递一个外部用户id以存储在“声明”列中。CSV中总共

我正在创建我的第一个Node.js REST API测试项目,它可以检索奖品。该逻辑旨在执行以下操作:

  • 从与项目关联的Google云存储桶中检索CSV
  • 解析CSV
  • 查找未填充列“Claimed”的第一行
  • 将“索赔”列更新为“索赔!”
  • 覆盖Google云存储中CSV文件中的数据
  • 返回与该行关联的奖品名称
我的逻辑目前在本地工作,但我想知道是否有更好、更可伸缩的方法来编写代码。我将以每天约10万用户的500/分钟的速率限制对其进行测试,并最终传递一个外部用户id以存储在“声明”列中。CSV中总共有50万行(奖品)

下面是我正在使用的代码。如果您有任何使其可扩展的建议,我们将不胜感激!先谢谢你

const csv = require('csv-parser');
const fs = require('fs');
const jsonexport = require('jsonexport');

const bucketName = 'MY-BUCKET';
const filename = 'MY-CSV';

const {Storage} = require('@google-cloud/storage');

const storage = new Storage({keyFilename: "MY-KEY.json"});

const myBucket = storage.bucket(bucketName);
const file = myBucket.file(filename);

let dataArray = [];

file.createReadStream()
  .pipe(csv())
  .on('data', function (data) {
    dataArray.push(data);
  })
  .on('end', function(){
    let prize = dataArray.find(element => element.Claimed == "");
    prizeName = prize.Prize_name;
    prize.Claimed = "claimed!";
    jsonexport(dataArray,function(err, transformedData){
      if(err) return console.log(err);
      file.save(transformedData, function(err) {
        if(err) return console.log(err);
      });
    });
    return prizeName
});

好吧,我有这方面的经验。根据一个问题,更多的是关于性能,我建议基本代码可以正常工作

我想瓶颈是
fs
createReadStream
。它工作正常,但不是异步的()

实际上是,但是。。。如果您想立即存储文件,您的RAM将被文件淹没

因此,即使您有10个用户数为50k的文件,而不是一个用户数为500k的文件。。您将需要一次解析所有10个,但在同步执行时

嗯,你的逻辑不会像你想象的那样工作得更快

顺便说一下,如果您有另一个代码具有相同的功能,但您不知道如何衡量它的性能和速度,请使用以下方法:

我知道我的答案根本不是答案,但这就是我解决这个问题的方式,就像我是你一样:

  • 删除CSV-它只会给您带来问题,尤其是当您处理100K+行时
  • 尝试云基础设施:如果您需要将数据存储在某处,请使用例如。不要忘了在相关列上添加一些索引。所以现在,您不需要
    fs
    ,它完全是流式的
在本例中,关注Mongo Atlas只是一种选择,您可以使用它,或者其他任何东西。甚至可以使用/启动任何适合您需要的数据库。关键是,-远离谷歌表单/硬盘

为什么要避免使用CSV/Google驱动器

正如你可能认为的那样,它们并没有那么糟糕,但你会问自己,如果google drive/csv是存储数据的有效方式,为什么人们使用数据库而不是将所有信息存储在一个大的
*.csv
文件中?我想这个比喻是有道理的

那么回到我们未来的数据库

现在,您只需要连接到数据库并修改它的值。您可以通过一个查询立即修改所需的所有内容,而不是:

let prize = dataArray.find(element => element.Claimed == "");
您不需要逐个查找每一行。这就是你所问的问题

您唯一需要的是:AWS Lambda、MongoDB Stitch/Realm、webhook、API来修改数据库中的数据或添加到表单中(如果您的数据应该通过http表单更新)。顺便说一句,如果你害怕并且还没有准备好跳转并将Google Sheets抛在身后,你可以(在这种情况下,它是MongoDB,但是Google Sheets支持Google脚本,所以连接任何其他DB都不会是一个大问题)

因此,所有这些步骤都将帮助您的应用程序按照您的要求更具可伸缩性。此外,使用DB将解决数据验证等方面的任何其他问题

作为一个相反的站点,在我的一个项目中,我依赖于一个数据源,它实际上发布了一个大的
*.csv
表单。它有多大?65K+行,并查找和更新其中的每个值,需要7-12分钟的资源时间。天啊,我真讨厌那个家伙,他用csv而不是API端点/DB连接器


顺便说一下,欢迎来到StackOverflow!您的问题对于一个新用户来说格式很好,似乎已经阅读了()并了解了markdown editor。另外,不要忘了向提供有用数据的用户投票,并将问题标记为已回答,或与社区共享您自己的答案。以防你自己发现。让我猜猜,你之所以使用处理
*.csv
,仅仅是因为在你的项目中使用谷歌表单作为前端界面?您好@AlexZeDim,谢谢您的回复和好话!我会确保对回答的问题进行投票和打分,谢谢你的建议我使用了一个
*,csv
,因为我想让数据在谷歌云存储和谷歌工作表之间来回移动变得容易。例如,从工作表下载数据作为CSV是很容易的。你能建议另一种格式吗?是的,如果我是你的话,我只是键入一个答案。非常感谢你的详细回复!这非常有用。我有一个关于你所说的立即修改所有内容的问题。由于将从中调用API的工具的结构,此过程需要一次完成一个,而不是批量完成。一个API调用需要检索一个奖品,然后用一个用户更新这一行。这会改变你的答案吗?--另外,您是否建议使用DB?我想选择自由层最大的。@user5779866m好吧,这取决于你需要多少操作。我的意思是,您喜欢通过
js
code使用DB手动触发脚本进行操作,这样您就根本不需要httpapi端点了。但是,例如,如果我是
用户
并且想加入你的赠品,那么我应该以某种方式注册。因此,我应该要求您手动将我添加到您的DB中,或者通过
通过web表单注册自己进行操作,当我按
注册
按钮时,AWS Lambda或Mongo Stitch会将我添加到您的DB中。@user5779866至于DB,由您决定。利用一切
console.time('benchmark_name')
/* Some action here */
console.timeEnd('benchmark_name')
let prize = dataArray.find(element => element.Claimed == "");