【问题标题】:Why does loading data into a Meteor Collection take so long?为什么将数据加载到 Meteor Collection 需要这么长时间?
【发布时间】:2013-11-02 04:20:27
【问题描述】:

我正在尝试使用 Meteor 构建一个数据可视化应用程序来可视化大型数据集。数据目前存储在 CSV 格式的数据文件中,大小约为 64MB。

我正在使用 node-csv 插件将此数据文件加载到 Meteor 集合中(代码如下)。但是每 10k 条记录大约需要 1 分钟,按照这个速度,将整个文件加载到集合中大约需要 1.5 小时。在此期间,Meteor 服务器对 Web 请求没有响应。

这对我来说似乎异常缓慢。这是正常的吗? Meteor 是不是设计用于处理中等数量的数据?或者有没有比我发现的方法更好的方法来完成这个数据导入过程?

var csv = Meteor.require('CSV');
var fs = Meteor.require('fs');
var path = Npm.require('path');

function loadData() {
  var basepath = path.resolve('.').split('.meteor')[0];
  console.log('Loading data into Meteor...');

  csv().from.stream(
    fs.createReadStream(basepath+'server/data/enron_data.csv'),
      {'escape': '\\'})
    .on('record', Meteor.bindEnvironment(function(row, index) {
      if ((index % 10000) == 0) {
        console.log('Processing:', index, row);
      }
      Emails.insert({
        'sender_id': row[0],
        'recipient_id': row[1],
        'recipient_type': row[2],
        'date': row[3],
        'timezone': row[4],
        'subject': row[5]
        })
      }, function(error) {
          console.log('Error in bindEnvironment:', error);
      }
    ))
    .on('error', function(err) {
      console.log('Error reading CSV:', err);
    })
    .on('end', function(count) {
      console.log(count, 'records read');
    });
}

【问题讨论】:

  • 我想不使用集合并直接访问数据库会快得多。话虽这么说,我需要更多信息才能给你一个真正的分析器。你什么时候运行loadData?例如这是您本地开发数据库的初始化代码吗?你删除了autopublish 包吗?
  • 您应该使用直接批量导入,而不是逐行插入。在某些数据库上,您可以暂时禁用约束、索引等,并等待直到最后一条记录被批量导入。这可能意味着提速一到两个数量级。
  • @DavidWeldon 它位于本地开发服务器的 Meteor.startup() 部分。即使删除了自动发布,它仍然需要相同的时间。
  • @TFuto 你能告诉我如何用 Meteor/MongoDB/NodeCSV 做到这一点吗?如果可以的话,我通常会进行批量导入,但我能找到的 Meteor+CSV 的唯一接口使用的是逐行回调。
  • 考虑给插入函数一个回调。 “在服务器上,如果您不提供回调,则插入块,直到数据库确认写入,或者如果出现问题则抛出异常。” - docs.meteor.com#insert

标签: javascript node.js csv meteor


【解决方案1】:

即使您在流星环境之外执行此操作,一次加载一行数据也确实效率低下。我想你想要的工具是mongoimport

这可能不是很明显,但您不需要插入带有流星的文档即可在文档中使用流星。

当您的集合中有 0 个文档时(或任何对您的情况有意义的基本条件),您可以尝试从 Meteor.startup 调用 mongoimport。我还没有尝试过,所以我不能说这是多么痛苦,但我想你可以打电话给child_process.spawn 来启动 mongoimport。如果由于某种原因不起作用,您可以随时将其放入脚本中,并在您执行meteor reset 时运行该脚本。

旁注 - 我相信您的静态服务器资产的合适位置是 private 目录。这也让您可以使用Assets api 来访问这些文件。

【讨论】:

  • 谢谢,mongoimport 完美运行。我没有意识到我可以在 Meteor 环境之外导入数据,但这显然是正确的解决方案。
猜你喜欢
  • 2012-12-06
  • 2019-11-13
  • 2011-12-07
  • 2022-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多