I am inserting data from CSV
file, I want to update if the object key has the same then the new price will just update, I have used csvtojson
for parsing CSV files and multer
for file upload.
CSV file has itemNumber, title, and price column
sample.csv
itemNumber,title,price
STY0047,Men Straight Fit Jeans,2500
STY0048,Men Straight Fit Jeans,2450
STY0049,Men Straight Fit Jeans,2550
STY0050,Men Straight Fit Jeans,3000
STY0048,Men Straight Fit Jeans,4000
STY002,Men Straight Fit Jeans,2550
STY0053,Men Straight Fit Jeans,3000
STY0054,Men Straight Fit Jeans,3000
STY0043,Men Straight Fit Jeans,4000
My code
router.post("/file-insert-data", upload, async function (req, res, next) {
if (!req.file) {
return res.status(400).send("no file found");
}
const results = await csv().fromFile(req.file.path);
for (let obj in results ) {
const csvData = new csvModel(results [obj])
csvData.save((err, data) => {
if(err) {
return res.status(400).send("csv data is not inserted")
}
return res.status(201).send(data)
})
}
});
Help me Thanks
Santiago Trujillo
UPDATED
After some collab with the OP, here is mongoose-friendly version that aligns with the original question. It highlights upsert
functionality and features generic addition of new fields.
results.forEach(function (item) {
var prx = item['price']; // capture price....
// ...and now REMOVE it. This is because fields cannot appear in
// both $set and $setOnInsert. Our trick here is to make the $setOnInsert
// generic. ANY fields that are NOT itemNumber or price will automatically
// be added upon first insert. It should be obvious that if you need
// to upsert more things (i.e. more things to $set), then delete them from
// the object too. Note: $setOnInsert will only store the fields from
// item upon first insert. New fields in later items with an existing
// key will NOT be updated. Comment out the delete and see the error
// message re. path conflict:
delete item['price'];
rc = csvModel.findOneAndUpdate(
{ itemNumber: item["itemNumber"] },
{
$set: { price: prx },
$setOnInsert: item // Ah! Set the WHOLE OBJECT.
},
{ upsert: true }
);
rc.then(data => data)
});
findOne
function to check if the element already exists (I assume that itemNumber
is key for the model).csvModel
router.post('/file-insert-data', upload, async function (req, res, next) {
if (!req.file) {
return res.status(400).send('no file found');
}
try {
const results = await csv().fromFile(req.file.path);
let updatedData = []; // Array to store the updated data
for (const item of results) {
const { itemNumber, title, price } = item;
let csvData = await csvModel.findOne({ itemNumber });
if (!csvData) {
// Create new data if not present
csvData = new csvModel();
csvData.itemNumber = itemNumber;
csvData.title = title;
}
// Update the price
csvData.price = price;
// Save the created / updated data
await csvData.save();
updatedData.push(csvData);
}
return res.status(201).send(updatedData);
} catch (err) {
return res.status(500).send('Error updating data');
}
});