#node.js #mongodb #csv #mongoose
#node.js #mongodb #csv #мангуст
Вопрос:
У меня есть node.js сервер, что я пытаюсь сделать, это прочитать имя файла csv с помощью запроса post, который затем предложит серверу прочитать CSV-файл в кодировке UTF-8 для чтения, который помещается в папку public / files внутри внутренней папки, и строка за строкой каждая запись вводится в mongodb.
Но возникающая проблема заключается в том, что в mongodb вводится только 50 записей.
Ответ «ВСЕ округлости добавлены успешно» отправляется в postman, но консоль продолжает показывать «Добавленный округлый» console.log .
Я хотел бы знать, что я делаю не так, поскольку я некоторое время ждал, но Robo 3T показывает только 50 записей в коллекции Allrounder.
Node.js серверная часть :
router.post(("/allrounders/addFile"),(req, res) =>
{
const file_name = req.body.name;
const file_path = path.join(__dirname,"..","public","files",`${file_name}.csv`);
let stream = fs.createReadStream(file_path);
stream.pipe(csv())
.on('data', (row) => {
var name = (row['Name']);
var country = (row["Country"]);
var starting_year = (row['Starting Year']);
var ending_year = (row['Ending Year']);
var matches = (row["Matches"]);
var Batting_Runs = (row['Batting Runs']);
var highest_score = (row['Highest Score']);
var Batting_Average = (row['Batting Average']);
var Hundreds = (row["Hundreds"]);
var Wickets = (row["Wickets"]);
var best_bowling_figures_wickets = (row['Best Bowling Figures Wickets']);
var best_bowling_figures_runs = (row['Best Bowling Figures Runs']);
var Bowling_Average = (row['Bowling Average']);
var five_Wickets = (row['5 Wickets']);
// Difference between batting and bowling average. , if ve then a better batsman, else bowler
var Average_Difference = (row['Average Difference']);
let wickets2;
// WIckets
if(Wickets.includes("-"))
{
wickets2 = 0
}
else
{
wickets2 = Wickets
}
// Best FIgures
let best_bowling_figures_wickets2;
let best_bowling_figures_runs2;
if(best_bowling_figures_wickets.includes("-"))
{
best_bowling_figures_wickets2 = 0;
}
else
{
best_bowling_figures_wickets2 = best_bowling_figures_wickets
}
if(best_bowling_figures_runs.includes("-"))
{
best_bowling_figures_runs2 = 0;
}
else
{
best_bowling_figures_runs2 = best_bowling_figures_runs;
}
// Bowling average
let Bowling_Average2;
if(Bowling_Average.includes("-"))
{
Bowling_Average2 = 0;
}
else
{
Bowling_Average2 = Bowling_Average;
}
// Five wickets
let five_Wickets2;
if(five_Wickets.includes("-"))
{
five_Wickets2 = 0;
}
else
{
five_Wickets2 = five_Wickets;
}
// Average difference
let Average_Difference2;
if(Average_Difference.includes("-"))
{
Average_Difference2 = 0;
}
else
{
Average_Difference2 = Average_Difference;
}
// highest score
var out_status_for_highestscore;
if(highest_score.includes("*"))
{
out_status_for_highestscore = false;
}
else
{
out_status_for_highestscore = true;
}
let temp_var_highestscore = highest_score.split("*");
var highest_score_runs = temp_var_highestscore[0];
// Make new obj to be saved in DB
const newAllrounder = new Allrounder({
name: name,
country: country,
wicket_keeper : false,
span: {starting_year : starting_year,
ending_year:ending_year },
matches: matches,
batting_runs:Batting_Runs,
highest_score:{
highest_runs : highest_score_runs,
out: out_status_for_highestscore
},
batting_average: Batting_Average,
hundreds:Hundreds,
wickets:wickets2,
best_figures:{
runs : best_bowling_figures_runs2,
wickets:best_bowling_figures_wickets2
},
bowling_average:Bowling_Average2,
five_wickets:five_Wickets2,
average_difference:Average_Difference2
});
newAllrounder.save()
.then(results =>console.log("Allround added"))
.catch(err => res.status(400).json("Error saving All rounders " err));
})
.on('end', () => {
console.log('CSV file successfully processed');
res.json("ALL rounders added successfully");
}
)
.on('error', () => {
res.status(400).json("Error Processing the CSV file correctly");
});
});
Моя универсальная модель :
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const allrounderSchema = new Schema(
{
name:
{
type: String,
required: true,
minlength: 3,
trim: true
},
country:
{
type: String,
required: true,
minlength: 2,
trim: true
},
wicket_keeper :
{
type: Boolean,
required: true,
trim: true
},
span:
{
starting_year :
{
type:Number,
required: true,
trim: true
},
ending_year:
{
type:Number,
required: true,
trim: true
}
}
,
matches:
{
type:Number,
required: true,
trim: true
},
batting_runs:
{
type:Number,
required: true,
trim: true
},
highest_score:
{
highest_runs :
{
type:Number,
required: true,
trim: true
},
out:
{
type: Boolean,
required: true,
trim: true
}
}
,
batting_average:
{
type:Number,
required: true,
trim: true
},
hundreds:
{
type:Number,
required: true,
trim: true
},
wickets:
{
type:Number,
required:true,
trim: true
}
,
best_figures:
{
runs :
{
type:Number,
required: true,
trim: true
},
wickets:
{
type: Number,
required: true,
trim: true
}
},
bowling_average:
{
type:Number,
required: true,
trim: true
},
five_wickets:
{
type:Number,
required: true,
trim: true
},
average_difference:
{
type:Number,
required: true,
trim: true
}
});
const Allrounder = mongoose.model("Allrounder",allrounderSchema);
module.exports = Allrounder;
Ответ №1:
На стороне вашего сервера чтение не приостановлено, и, сохраняя ваш объект MongoDB, вы получаете обещание. Что вам следует сделать, так это сохранить ваш readable в переменной вместо прямого вызова метода .on(). Если вы сохраните свои читаемые данные, вы сможете приостановить и возобновить свои CSV-данные, чтобы избежать пропуска некоторых записей. Используйте следующий код:
router.post(("/allrounders/addFile"),(req, res) =>
{
const file_name = req.body.name;
const file_path = path.join(__dirname,"..","public","files",`${file_name}.csv`);
let readable = fs.createReadStream(file_path).pipe(csv());
readable.on('data', (row) => {
var name = (row['Name']);
// Your code ...
// Make new obj to be saved in DB
// Your object Defined
readable.pause() // HERE pause your readable
newAllrounder.save()
.then(results => {
console.log("Allround added");
readable.resume(); // When you promise is resolved you resume your readable
})
.catch(err => res.status(400).json("Error saving All rounders " err));
});
readable.on('end', () => {
console.log('CSV file successfully processed');
res.json("ALL rounders added successfully");
});
readable.on('error', () => {
res.status(400).json("Error Processing the CSV file correctly");
});
});
Комментарии:
1. Хосе Васкес, спасибо, это сработало. Но я обнаружил кое-что глупое, что на самом деле вызывало эту проблему, дело в том, что мой предыдущий код тоже работал, но загруженный мной набор данных был неправильным, поскольку в нем было всего 50 строк, которые повторялись несколько раз, пока не достигли 2500 строк. я исправил это, и проблема была устранена.
Ответ №2:
newAllrounder.save()
является асинхронным. Цикл не ожидает его завершения перед началом следующей итерации. Когда цикл завершается, он возвращается, даже если к этому моменту многие операции сохранения не завершены. По мере завершения каждой из них выполняется then
, поэтому эти сообщения продолжаются даже после отправки ответа.