mongodb 无法创建一个文档,其中有另一个嵌入的文档

qvtsj1bj  于 12个月前  发布在  Go
关注(0)|答案(1)|浏览(133)

在学习了node.js + mongodb教程之后,我试图构建一个小项目。但我被卡住了。我试图构建一个小型电子商务API。我有一个卖家集合,还有一个库存集合。卖家可以有很多库存物品。我已经成功创建了卖家集合,现在我正在尝试创建库存集合。我已经将卖家嵌入到库存中:
models/inventory.js

const { sellerSchema } = require("./seller");
.
.
.
const inventorySchema = new mongoose.Schema({
  itemName: { type: String, required: true, minlength: 3, maxlength: 30 },
  itemDescription: { type: String, required: true, minlength: 10 },
  // look into how to upload and handle images on mongodb
  // image:,
  quantity: { type: Number, required: true, min: 0, max: 999 },
  category: { type: String, required: true, minlength: 20 },
  price: { type: Number, required: true, min: 0 },
  seller: { type: sellerSchema, required: true },
});

const Inventory = mongoose.model("Inventory", inventorySchema);

exports.Inventory = Inventory;

字符串
routes/inventories.js

const { Seller } = require("../models/seller");
const { Inventory } = require("../models/inventory");
.
.
.
router.post("/", async (req, res) => {
  const seller = await Seller.findById(req.body.sellerId);
  if (!seller) return res.status(400).send("Seller not found");

  let inventory = new Inventory({
    itemName: req.body.itemName,
    itemDescription: req.body.itemDescription,
    quantity: req.body.quantity,
    category: req.body.category,
    price: req.body.price,
    seller: { _id: seller._id, name: seller.name },
  });

  inventory = await inventory.save();
  res.send(inventory);
});


当我尝试在postman http://localhost:3000/api/inventories/上运行这个命令来创建一个物品时,失败了。找不到卖家。这是我在postman上发送的对象:

{"itemName": "itemName1",
"itemDescription": "itemDescription1",
"quantity": 1,
"category": "category1",
"price": 1,
"seller":"6531ea0358367cd5d863600d"
}


6531ea0358367cd5d863600d是数据库中现有卖家的ID。我从我成功添加到卖家集合的卖家中提取了卖家ID。我缺少什么?任何帮助或指针将不胜感激。谢谢!

whlutmcx

whlutmcx1#

因此,快速修复答案是将req.body.sellerId更改为req.body.seller,并将seller文档添加到new Inventory()文档中,如下所示:

const seller = await Seller.findById(req.body.seller); //< req.body.seller
if (!seller) return res.status(400).send("Seller not found");

let inventory = new Inventory({
    itemName: req.body.itemName,
    itemDescription: req.body.itemDescription,
    quantity: req.body.quantity,
    category: req.body.category,
    price: req.body.price,
    seller: seller //< Add the seller object. That's what your inventorySchema expects
  });

//...
//...

字符串
这是因为在postman数据对象中没有sellerId,只有seller

长的答案是通过使用引用文档来改进数据建模。此时,您将向每个Inventory文档添加Seller文档。如果您的Seller详细信息发生更改,会发生什么?这些更改不会级联到每个Inventory文档中。

相反,只需在每个Inventory文档中添加对Seller的引用。

const inventorySchema = new mongoose.Schema({
  itemName: { type: String, required: true, minlength: 3, maxlength: 30 },
  //...
  //...
  seller: { type: mongoose.Schema.Types.ObjectId, ref: 'Seller', required: true },
});


然后,当您创建new Inventory({})文档时:

let inventory = new Inventory({
    itemName: req.body.itemName,
    //...
    //...
    seller: seller._id, //< Only add the seller ObjectId
  });


现在,如果您的Seller详细信息发生更改,它们只会在Seller文档中发生更改。无论您更改多少次,您的新引用都将始终指向同一文档。这提高了数据一致性并减小了文档大小。
当你想获取包含Seller文档的Inventory文档时,你可以使用Model.populate,它会将这些新引用与相应的Seller切换,如下所示:

const inventory = Inventory.findById(id).populate('seller');
// or if the models havn't been registred
const inventory = Inventory.findById(id).populate({path: 'seller', model: Seller});

相关问题