【问题标题】:How to update data if same key exists in mongodb?如果mongodb中存在相同的键,如何更新数据?
【发布时间】:2021-12-31 14:09:11
【问题描述】:

我正在从CSV 文件插入数据,如果对象键相同,我想更新新价格,我使用csvtojson 解析CSV 文件和multer 用于文件上传。

CSV 文件包含 itemNumber、title 和 price 列

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

我的代码

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

帮帮我谢谢

【问题讨论】:

  • 您可以在阅读 csv 文件后发布console.log(results) 的结果吗?
  • 我正在获取保存在 sample.csv 文件中的数组,[ { itemNumber: 'DNFJAV001-SK-STY0047', title: 'Men Straight Fit Jeans', price: '2500' }, { itemNumber: 'DNFJAV001-SK-STY0048', title: 'Men Straight Fit Jeans', price: '2450' } ] 有更多对象,但我不能在这里发布它,因为你知道更多行不能作为评论接受
  • mongoimport 工具怎么样?它支持 CSV 文件,也支持。
  • 请编辑您的问题以获取此类附加信息,而不是将其作为评论。

标签: javascript node.js mongodb express


【解决方案1】:
  1. 尝试使用findOne 函数来检查元素是否已经存在(我假设itemNumber 是模型的关键)。
  2. 如果没有,则创建csvModel 的新实例
  3. 更新价格
  4. 保存数据
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');
  }
});

【讨论】:

    【解决方案2】:

    更新

    在与 OP 合作后,这里是与原始问题一致的猫鼬友好版本。它突出了upsert 的功能并具有通用添加新字段的特点。

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

    【讨论】:

    • 请告诉我rc的方法
    • rc 只是调用updateOne 的返回码。您可以通过printjson(rc); 查看返回的信息。这对本例来说不是必需的。
    • 如果我使用 csvModel 而不是 db.foo 它将起作用,因为我正在使用 mongoose 进行此操作
    • 我谨慎地说“是”。这里没有什么会与 Promises 等混淆。我不是猫鼬专家。 csvData 是 javascript 对象吗?如果是这样,那似乎是上面答案中item 的替代品。
    • 尝试将await 放在某处。这里的关键是$set/$setOnInsert 功能。我无法为node.js 和猫鼬和模型等提供强有力的帮助。
    猜你喜欢
    • 1970-01-01
    • 2015-07-21
    • 2019-12-20
    • 1970-01-01
    • 1970-01-01
    • 2019-04-25
    • 2020-01-06
    • 2021-12-20
    • 1970-01-01
    相关资源
    最近更新 更多