返回

MongoDB 中添加新对象后,如何更改之前添加的对象的图像名称?

javascript

MongoDB: 添加新对象后更改之前添加的对象

引言

在构建全栈应用程序时,有时会出现令人困惑的问题。例如,在一个使用 AWS S3 和 MongoDB 的 React 应用程序中,向前端添加新食谱时,后端创建的 rndImageName 有时会更改。这篇文章将深入探讨这一问题,并提供逐步解决问题的指南。

问题根源

该问题的根源在于未正确生成和使用唯一的 rndImageName。在 multer.js 中,用于生成图像名称的函数是全局变量,这意味着它会在处理不同请求时被覆盖。这导致为不同的食谱分配了相同的图像名称。

解决方法

为了解决这一问题,我们采取了以下步骤:

  1. 创建唯一的随机图像名称: 使用 uuid 包在 multer.js 中生成唯一的随机图像名称。
  2. 使用随机图像名称上传到 S3: 使用 rndImageName 作为 S3 对象的名称,确保每个图像都有不同的名称。
  3. 将图像名称存储在 MongoDB 中:rndImageName 存储在 MongoDB 文档的 imageName 字段中,以便将来使用。
  4. 避免使用全局变量: 确保 rndImageName 是一个局部变量,而不是全局变量,以防止在处理不同请求时覆盖相同的图像名称。

实现细节

multer.js

const { v4: uuidv4 } = require('uuid');

awsRouter.post('/recipeImages', upload.single('file'), async (req, res) => {

  const buffer = await sharp(req.file.buffer).resize({ height: 1920, width: 1080, fit: 'contain' }).toBuffer()

  const rndImageName = uuidv4();

  const params = {
    Bucket: bucketName,
    Key: 'recipeImages/' + rndImageName, 
    Body: buffer,
    ContentType: req.file.mimetype
  }

  const command = new PutObjectCommand(params)

  await s3.send(command)

})

recipes.js

recipesRouter.post('/', async (request, response, next) => {

  const body = request.body

  const decodedToken = jwt.verify(getTokenFrom(request), process.env.SECRET)

  if (!decodedToken.id) {
    return response.status(401).json({ error: 'token invalid' })
  }
  const user = await User.findById(decodedToken.id)


  const recipe = new Recipe({
    // ...
    imageName: rndImageName,
    // ...
  })

  const savedRecipe = await recipe.save()
  user.recipes = user.recipes.concat(savedRecipe._id)
  await user.save()

})

结论

通过这些更改,我们可以确保每个食谱都使用唯一的 rndImageName,从而避免了 MongoDB 中名称冲突的问题。这使我们能够为特定食谱创建 SignedURL,并保持图像名称的正确性。

常见问题解答

  1. 为什么会出现名称冲突的问题?

    • 由于使用全局变量生成 rndImageName,它在处理不同请求时被覆盖,导致为不同的食谱分配了相同的图像名称。
  2. 如何避免名称冲突?

    • 使用 uuid 包生成唯一的随机图像名称并将其作为局部变量存储。
  3. 使用 rndImageName 有什么好处?

    • 避免名称冲突,允许为每个食谱创建唯一的 SignedURL,从而确保图像名称的正确性。
  4. 实现这些更改会对性能产生什么影响?

    • 生成和存储唯一的 rndImageName 可能对性能产生轻微的影响,但它是避免名称冲突并确保数据完整性的必要权衡。
  5. 这些更改适用于其他需要处理文件上传的应用程序吗?

    • 是的,这些更改可以应用于需要处理文件上传的任何应用程序,不仅限于 MongoDB 和 AWS S3。