如何将数据从CSV文件导入服务器端的Meteor集合 [英] How to import data from CSV file into Meteor collection at server side

查看:282
本文介绍了如何将数据从CSV文件导入服务器端的Meteor集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为我上一篇文章找到解决方案: Mongo在Meteor应用程序的_id_字段中出现重复的键错误



为了这样做,我想从我的CSV文件读取数据



首先我在这篇文章中尝试了解决方案使用node-csv和meteor文件将CSV导入集合,但meteor文件不是与当前版本的Meteor兼容。我也尝试过此上传数据到Meteor / Mongo DB 的解决方案,但是它也在客户端上,该解决方案生成与我上一篇文章中相同的错误。



经过一些进一步的研究,我试图用下面的代码读取数据。但它不工作:



首先我创建了一个集合:

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

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

 < template name =read_file_orders> 
< form class =well form-inline>
< label class =control-labelfor =fileInput2> Kies bestand< / label>
< input class =input-fileid =fileInput2type =filename =files []>
< Button class =btn btn-primaryid =read_orders> Importeer< / button>
< button class =btn btn-dangerid =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(){
//启动时在服务器上运行的代码

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\\\
');
var l = lines.length - 1;
for(var i = 0; 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(%);
};

当我尝试读取文件时,没有任何反应。只有控制台日志显示在服务器控制台中,但没有导入。即使没有创建订单集合。



很明显,我做错了,但我不知道究竟是什么。但我认为解决不太远。





编辑:



为了revens的答案这里是我的testapp的完整代码:



test.html:

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

< body>
< h1>欢迎来到Meteor!< / h1>
{{> read_file_orders}}
< / body>

< template name =read_file_orders>
< form class =well form-inline>
< label class =control-labelfor =fileInput2> Kies bestand< / label>
< input class =input-fileid =fileInput2type =filename =files []>
< Button class =btn btn-primaryid =read_orders> Importeer< / button>
< button class =btn btn-dangerid =erase_orders> Wis gegevens< / button>
< / form>
< / template>

test.js

  Orders = new Mongo.Collection(orders); 

if(Meteor.isClient){
//计数器从0开始

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

import_file_orders = function(file){
console.log(enter function import_file_orders)
var lines = file.split(/ \r\\\
| \ n /);
var l = lines.length - 1;
for(var i = 0; 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){
//加载文件时,回调函数以字符串形式调用内容
var reader =新FileReader();
reader.onload = function(e){
var contents = e.target.result
onLoadCallback(contents);
}
reader.readAsText(f);
};

}

if(Meteor.isServer){
Meteor.startup(function(){
//启动时在服务器上运行的代码

});

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

}


解决方案

很接近。



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

  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 /);

这使得单独的行被拆分成数组的成员。然后我假设,因为你调用你的输入一个CSV,你的值用逗号分隔,而不是管道。所以我把你的line.split改成了这个

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

我做的其他更改可能不是导致您失败的原因,但这是我的想法



 <$ c $ 

c> 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));

在问题中更新代码的EDIT:



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


I'm trying to find a solution for my previous post: Mongo gives duplicate key error on _id_ field in Meteor application

In order to do that I want to read data from my CSV file at server side, and not from the client.

First I tried the solution in this post Using node-csv and meteor-file to import CSV into a collection but meteor-file isn't compatible anymore with current version of Meteor. I also tried the solution in this post Upload Data to Meteor / Mongo DB but It's also on the client and that solution generates the same error as in my previous post.

After some further research I tried to read the data with the code below. However it doesn't work:

First I created a collection:

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

I defined the following template to read the csv file:

<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>

This is the client 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);
};

And this is the server 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("%");
};

When I try reading the file, nothing happens. Only the console logs appear in the server console but there is nothing imported. Even the Orders collection isn't created.

It's clear that I'm doing something wrong but I don't know what exactly. However I think the solution isn't too far. Maybe someone of you can show me the right direction?

Kind regards

EDIT:

In order to revmen's answer here's the full code of my 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");
 }
});

}

解决方案

You were very close. I just had to make a few changes to get it working.

I don't know what your .csv file looks like, so I made one that's like this:

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

Your file.split operation wasn't splitting the lines, but was putting everything on one big line. I did it this way and it worked:

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

That got individual lines to split into members of the array. Then I assumed that, since you're calling your input a CSV, your values are separated by commas, not pipes. So I changed your line.split to this

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

Other changes I made may not be what was causing yours to fail, but this is how I think things are normally done...

Instead of declaring your collection like this

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

I did it like this

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

Note that this is run by both the server and the client.

Instead of your way of declaring methods on the server, I just put this into server code (not in Meteor.start):

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

And, of course, I changed the insert line at the bottom of your import_file_orders function

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));

EDIT for updated code in the question:

Move the import_file_orders function from the client block to the server block.

这篇关于如何将数据从CSV文件导入服务器端的Meteor集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆