mongodb mongoose抱怨重复的id

doinxwow  于 2023-11-17  发布在  Go
关注(0)|答案(2)|浏览(115)

简单来说,我正在使用ReactJS,Node.js + mongoDB创建一个Web应用程序。它的目的是保存食物和产品的列表,并从中轻松创建购物清单。
我对Node.js和MongoDB完全没有经验,并且沿着在学习创建这个应用程序的方法,因此我需要你的帮助来解决一个问题。
mongoose中的productSchema看起来像这样:

{
  uniqueId: {
    type: String,
    required: true,
    default: () => nanoid(),
    index: { unique: true },
  },
  productName: {
    type: String,
    required: true,
  },
}

字符串
mealSchema:

{
  uniqueId: {
    type: String,
    required: true,
    default: () => nanoid(),
    index: { unique: true },
  },
  mealName: {
    type: String,
    required: true,
    trim: true,
  },
  products: [
    {
      uniqueId: {
        type: String,
        required: true,
        default: () => nanoid(),
        index: { unique: true },
      },
      productName: { type: String, ref: productSchema },
      productAmount: Number,
    },
  ],
}


正如你所看到的,mealSchema中的products数组与Product[]几乎相同,只是多了一个productAmount属性。
前端的逻辑是,当你创建一个新的Meal时,你可以添加尽可能多的产品(从产品列表中选择(从数据库中检索)或创建新的)。然后整个Meal被发送到后端,Meal在MongoDB集合中创建,之后,BE也会遍历每个产品,如果它不存在于'products'集合中,它也会被添加到那里。
我遇到了一个问题,当我试图创建一个Meal并添加一个已经存在于“products”集合中的Product时,后端返回一个错误:

{
  "error": "Could not create meal",
  "message": "E11000 duplicate key error collection: test.meals index: products.uniqueId_1 dup key: { products.uniqueId: \"ukmLU8nDtIXaBA7OzZD6R\" }"
}


有人能帮我解决这个问题吗?

yeotifhr

yeotifhr1#

E11000错误是由mongod服务器生成的。该错误意味着服务器拒绝创建文档,因为它会导致在使用选项“unique:true”显式创建的索引中出现重复键。
错误消息指出,“test.meals”集合中名为“products.uniqueId_1”的索引具有唯一选项,并且正在插入的文档包含{ products.uniqueId: "ukmLU8nDtIXaBA7OzZD6R" },但该值已存在于另一个文档中。
您是否打算限制该集合,以便只有一个文档可以引用相同的“products.uniqueId”值

mccptt67

mccptt672#

这是膳食控制器:

const express = require('express')
const router = express.Router()

// Import models
const Meal = require('../models/meal')
const Product = require('../models/product')

// Validation related imports
const validateSchema = require('../middleware/validate')
const mealValidation = require('../validation/mealValidation')

// Create a new meal
router.post('/', validateSchema(mealValidation), async (req, res) => {
  try {
    const meal = {
      _id: req.body._id,
      mealName: req.body.mealName,
      products: req.body.products,
    }

    await Meal.create(meal)

    const createdProducts = []
    const failedProducts = []

    for (const product of meal.products) {
      const existingProduct = await Product.findOne({
        productName: product.productName,
      }).exec()

      if (!existingProduct) {
        try {
          const newProduct = await Product.create(product)
          createdProducts.push(newProduct)
        } catch (error) {
          failedProducts.push({
            productName: product.productName,
            error: 'Failed to create product',
          })
        }
      }
    }

    if (failedProducts.length > 0) {
      res.status(207).json({
        meal,
        createdProducts,
        failedProducts,
      })
    } else {
      res.status(201).json(meal)
    }
  } catch (error) {
    res
      .status(500)
      .json({ error: 'Could not create meal', message: error.message })
  }
})

// Read all meals
router.get('/', async (_req, res) => {
  try {
    const meals = await Meal.find()
    res.status(200).json(meals)
  } catch (error) {
    res.status(500).json({ error: 'Could not fetch meals' })
  }
})

// Read a single meal by ID
router.get('/:id', async (req, res) => {
  try {
    const meal = await Meal.findOne({ _id: req.params._id })
    if (!meal) {
      return res.status(404).json({ error: 'Meal not found' })
    }
    res.status(200).json(meal)
  } catch (error) {
    res.status(500).json({ error: 'Could not fetch meal' })
  }
})

// Update a meal
router.put('/:id', validateSchema(mealValidation), async (req, res) => {
  try {
    const meal = await Meal.findByIdAndUpdate(req.params._id, req.body, {
      new: true,
    })
    res.status(200).json(meal)
  } catch (error) {
    res.status(500).json({ error: 'Could not update meal' })
  }
})

// Delete a meal
router.delete('/:id', async (req, res) => {
  try {
    await Meal.findByIdAndRemove(req.params._id)
    res.status(200).json({ message: 'Meal deleted successfully' })
  } catch (error) {
    res.status(500).json({ error: 'Could not delete meal' })
  }
})

module.exports = router

字符串
产品控制器:

const express = require('express');
const router = express.Router();

// Import model
const Product = require('../models/product');

// Validation related imports
const validateSchema = require('../middleware/validate');
const productValidation = require('../validation/productValidation');

// Create a new product
router.post('/', validateSchema(productValidation), async (req, res) => {
  try {
    const product = {
      _id: req.body._id,
      productName: req.body.productName,
    }

    await Product.create(product)
    res.status(201).json(product)
  } catch (error) {
    res
      .status(500)
      .json({ error: 'Could not create product', message: error.message })
  }
})

// Read all products
router.get('/', async (req, res) => {
  try {
    const products = await Product.find()
    res.status(200).json(products)
  } catch (error) {
    res.status(500).json({ error: 'Could not fetch products' })
  }
})

// Read a single product by ID
router.get('/:id', async (req, res) => {
  try {
    const product = await Product.findById(req.params._id)
    if (!product) {
      return res.status(404).json({ error: 'Product not found' })
    }
    res.status(200).json(product)
  } catch (error) {
    res.status(500).json({ error: 'Could not fetch product' })
  }
})

// Update a product
router.put('/:id', validateSchema(productValidation), async (req, res) => {
  try {
    const product = await Product.findByIdAndUpdate(req.params._id, req.body, {
      new: true,
    })
    res.status(200).json(product)
  } catch (error) {
    res.status(500).json({ error: 'Could not update product' })
  }
})

// Delete a product
router.delete('/:id', async (req, res) => {
  try {
    await Product.findByIdAndRemove(req.params._id)
    res.status(200).json({ message: 'Product deleted successfully' })
  } catch (error) {
    res.status(500).json({ error: 'Could not delete product' })
  }
})

module.exports = router;
enter code here

相关问题