【问题标题】:How to import data from CSV file into Meteor collection at server side如何将 CSV 文件中的数据导入服务器端的 Meteor 集合
【发布时间】:2015-05-14 22:18:53
【问题描述】:

我正在为我之前的帖子寻找解决方案:Mongo gives duplicate key error on _id_ field in Meteor application

为了做到这一点,我想在服务器端从我的 CSV 文件中读取数据,而不是从客户端读取数据。

首先我尝试了这篇帖子Using node-csv and meteor-file to import CSV into a collection 中的解决方案,但meteor-file 与当前版本的Meteor 不再兼容。我也在这篇帖子Upload Data to Meteor / Mongo DB 中尝试了解决方案,但它也在客户端上,并且该解决方案会产生与我之前帖子中相同的错误。

经过进一步研究,我尝试使用以下代码读取数据。但是它不起作用:

首先我创建了一个集合:

 Meteor.orders = new Meteor.Collection('Orders');

我定义了以下模板来读取 csv 文件:

<template name="read_file_orders">
  <form class="well form-inline">
   <label class="control-label" for="fileInput2">Kies bestand</label>
   <input class="input-file" id="fileInput2" type="file" name="files[]">
   <Button class="btn btn-primary" id="read_orders">Importeer</button>
   <button class="btn btn-danger" id="erase_orders">Wis gegevens</button>
  </form>
</template>

这是客户端javascript:

Template.read_file_orders.events({
 "click #read_orders" : function(e) {
  var f = document.getElementById('fileInput2').files[0];
  console.log("read file");
   readFile(f, function(content) {
    Meteor.call('upload',content);
   });
 }
});

readFile = function(f,onLoadCallback) {
 var reader = new FileReader();
 reader.onload = function (e){
  var contents=e.target.result
  onLoadCallback(contents);
 }
 reader.readAsText(f);
};

这是服务器javascript:

Meteor.startup(function () {
// code to run on server at startup

 return Meteor.methods({
  upload : function(fileContent) {
    console.log("start insert");
    import_file_orders(fileContent);
    console.log("completed");
  }
 });

});

import_file_orders = function(file) {
var lines = file.split('%\r\n');
var l = lines.length - 1;
for (var i=0; i < l; i++) {
  var line = lines[i];
  var line_parts = line.split('|');
  var ex_key = line_parts[0];
  var ex_name = line_parts[1];
  var clin_info = line_parts[2];
  var order_info = line_parts[3];
  var clinician_last_name = line_parts[4];
  var clinician_first_name = line_parts[5];
  var clinician_code = line_parts[6];
  var clinician_riziv = line_parts[7]
  var pat_id = line_parts[8];
  Meteor.orders.insert({Patient:pat_id, Exam_code:ex_key, Exam_name:ex_name, Clinical_info:clin_info, Order_info:order_info, Clinician_first:clinician_first_name, Clinician_last:clinician_last_name, Clinician_c_code:clinician_code, Clinician_riziv:clinician_riziv, Planned:null});
  console.log("%");
};

当我尝试读取文件时,没有任何反应。服务器控制台中仅显示控制台日志,但没有导入任何内容。甚至没有创建 Orders 集合。

很明显我做错了什么,但我不知道到底是什么。但是我认为解决方案还不算太远。也许你们中的某个人可以告诉我正确的方向?

亲切的问候

编辑:

为了 revmen 的回答,这里是我的 testapp 的完整代码:

test.html:

<head>
 <title>test</title>
</head>

<body>
 <h1>Welcome to Meteor!</h1>
 {{> read_file_orders}}
</body>

<template name="read_file_orders">
 <form class="well form-inline">
  <label class="control-label" for="fileInput2">Kies bestand</label>
  <input class="input-file" id="fileInput2" type="file" name="files[]">
  <Button class="btn btn-primary" id="read_orders">Importeer</button>
  <button class="btn btn-danger" id="erase_orders">Wis gegevens</button>
 </form>
</template>

test.js

Orders = new Mongo.Collection("orders");

if (Meteor.isClient) {
// counter starts at 0

Template.read_file_orders.events({
 "click #read_orders" : function(e) {
  var f = document.getElementById('fileInput2').files[0];
  console.log("read file");
  readFile(f, function(content) {
    Meteor.call('upload',content);
  });
 }
});

import_file_orders = function(file) {
 console.log("enter function import_file_orders")
 var lines = file.split(/\r\n|\n/);
 var l = lines.length - 1;
 for (var i=0; i < l; i++) {
  var line = lines[i];
  var line_parts = line.split(',');
  var ex_key = line_parts[0];
  var ex_name = line_parts[1];
  var clin_info = line_parts[2];
  var order_info = line_parts[3];
  var clinician_last_name = line_parts[4];
  var clinician_first_name = line_parts[5];
  var clinician_code = line_parts[6];
  var clinician_riziv = line_parts[7]
  var pat_id = line_parts[8];
  var result = Orders.insert({Patient:pat_id, Exam_code:ex_key, Exam_name:ex_name, Clinical_info:clin_info, Order_info:order_info, Clinician:{first:clinician_first_name, last:clinician_last_name, c_code:clinician_code, riziv:clinician_riziv}, Planned:null});
  console.log(Orders.findOne(result));
 };
}

readFile = function(f,onLoadCallback) {
//When the file is loaded the callback is called with the contents as a string
var reader = new FileReader();
reader.onload = function (e){
  var contents=e.target.result
  onLoadCallback(contents);
}
reader.readAsText(f);
};

}

if (Meteor.isServer) {
  Meteor.startup(function () {
  // code to run on server at startup

 });

 Meteor.methods({
   upload : function(fileContent) {
   console.log("start insert");
   import_file_orders(fileContent);
   console.log("completed");
 }
});

}

【问题讨论】:

  • 我正在使用相同的代码,但不幸的是,我在 reader.readAsText(f); 处收到了非人类可读的文本;有什么办法解析吗?

标签: javascript mongodb csv meteor


【解决方案1】:

你们很亲密。我只需要进行一些更改即可使其正常工作。

我不知道你的 .csv 文件是什么样的,所以我做了一个这样的:

A1, B1, C1, D1, E1, F1, G1, H1, I1
A2, B2, C2, D2, E2, F2, G2, H2, I2

您的 file.split 操作并未拆分行,而是将所有内容放在一条大行上。我是这样做的,它奏效了:

var lines = file.split(/\r\n|\n/);

这将单独的行拆分为数组的成员。然后我假设,由于您将输入称为 CSV,因此您的值由逗号分隔,而不是管道。所以我把你的 line.split 改成了这个

var line_parts = line.split(',');

我所做的其他更改可能不是导致您的失败的原因,但这是我认为通常做的事情...

而不是像这样声明你的收藏

Meteor.orders = new Meteor.Collection('Orders');

我是这样做的

Orders = new Mongo.Collection("orders");

请注意,这是由服务器和客户端运行的。

我只是将它放入服务器代码中(而不是在 Meteor.start 中),而不是您在服务器上声明方法的方式:

Meteor.methods({
    upload : function(fileContent) {
        console.log("start insert");
        import_file_orders(fileContent);
        console.log("completed");
    }
});

当然,我更改了 import_file_orders 函数底部的插入行

var result = Orders.insert({Patient:pat_id, Exam_code:ex_key, Exam_name:ex_name, Clinical_info:clin_info, Order_info:order_info, Clinician_first:clinician_first_name, Clinician_last:clinician_last_name, Clinician_c_code:clinician_code, Clinician_riziv:clinician_riziv, Planned:null});
console.log(Orders.findOne(result));

编辑问题中的更新代码:

将 import_file_orders 函数从客户端块移动到服务器块。

【讨论】:

  • 我尝试了这个解决方案,但不幸的是,没有成功。什么都没有发生。
  • 对我来说很棒!您能否从您的数据文件中发布几行,以便我们查看您要导入的内容?
  • 我在您的帖子中创建了一个类似的 CSV 文件。我认为我的代码本质上肯定有问题。似乎没有执行导入功能。我创建了一个小型测试应用程序来测试您的解决方案。我可以在我最初的帖子中在 EDIT 中发布代码吗?
  • 去吧。请务必记下您的代码所在的文件和目录。
  • Meteor.isClient 块中有 import_file_orders 函数。我把它移到了上传方法可以看到的 Meteor.isServer,现在它运行了。
猜你喜欢
  • 2017-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-19
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多