Home > Back-end >  mongoose save internal documents creating a document that contains a document
mongoose save internal documents creating a document that contains a document

Time:05-10

Im learning mongoose and i have a question how to save several documents:

// Product.js
const categorySchema = mongoose.Schema(
  { name: String },
  { collection: "categories" }
);
const productSchema = mongoose.Schema(
  { name: String, category: categorySchema },
  { collection: "products" }
);
modules.exports = mongoose.model("Product", productSchema);

The idea is that when I create a product this way

const Product = require("./Product.js")
const product = new Product({name: 'Soccer Ball', category: {name: "Sports"})
await product.save()

i want to get a document in the collection products and also a document in the collection categories

how can it be possible

thanks in advance

PD : Im getting this but category is not save in the collection

{
  "msg": "Product created succesfully",
  "ok": true,
  "product": {
    "name": "Soccer ball",
    "category": {
      "name": "Sports",
      "_id": "6275df4c8149967bea21e7c0"
    },
    "_id": "6275df4c8149967bea21e7bf",
    "__v": 0
  }
}

CodePudding user response:

You should define your Product's category as a ref attribute:

// Product.js
const categorySchema = mongoose.Schema(
    { name: String },
    { collection: 'categories' }
  );
const productSchema = mongoose.Schema(
    {
      name: String,
      category: { type: mongoose.Schema.Types.ObjectId, ref: 'categories' },
    },
    { collection: 'products' }
  );
modules.exports = {
    Category: mongoose.model('Category', categorySchema),
    Product: mongoose.model('Product', productSchema),
}

Doing this you will need to assign the _id of the category to the new Product:

const { Category } = require("./Product.js")
const { Product } = require("./Product.js")
// Create category (supposing it is not present)
const category = new Category({ name: "Sports" })
await category.save()
// Add category _id to product
const product = new Product({name: 'Soccer Ball', category: category._id})
await product.save()

Finally, you will be able to retrieve the product by using populate:

const product = await Product.findById(<product_id>).populate('categories').exec()

This query should give the same result than before, but the Category data will be loaded from the reference in the Category collection.

  • Related