NodeJS не удается сохранить все строки из csv в Mongodb

#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 , поэтому эти сообщения продолжаются даже после отправки ответа.