Reputation: 749
I created an e-commerce website but want to change a couple of features of it, I want to allow users to create unlimited categories and subcategories. what is the best approach for it? I used Nodejs (express) and MongoDB (mongoose). Currently, the DB schema is this one:
category.js
const mongoose = require('mongoose');
const { s, rs, n, ref } = require('../utils/mongo');
var schema = new mongoose.Schema(
{
user: ref('user'),
name: { ...rs, unique: true },
description: s,
image: s,
view: {
...n,
default: 0,
},
},
{ timestamps: true }
);
module.exports = mongoose.model('category', schema);
subcategory.js
const mongoose = require('mongoose');
const { s, rs, ref } = require('../utils/mongo');
var schema = new mongoose.Schema(
{
category: ref('category'),
name: { ...rs, unique: true },
description: s,
},
{ timestamps: true }
);
module.exports = mongoose.model('subcategory', schema);
Appreciate in advance
Upvotes: 0
Views: 2342
Reputation: 206
just use one model
import mongoose from "mongoose";
const CategorySchema = new mongoose.Schema({
name: {
type: String,
required: true,
unique: true
},
slug: {
type: String,
required: true,
unique: true
},
parent_id: {
type: mongoose.Schema.Types.ObjectId,
default: null
},
description: {
type: String,
default: null
},
image: {
url: String,
public_id: String
},
});
export mongoose.model('Category', CategorySchema);
// Create category
import { Category } from "./model/category.model"
const createCategory = async (data) => {
try {
return await new Category(data).save()
} catch (err) {
console.log(err)
}
}
// Get all category
const getAllCategory = async () => {
try {
const categories = await Category.find({});
if (!categories) return [];
return nestedCategories(categories);
} catch (err) {
console.log(err);
}
}
function nestedCategories(categories, parentId = null) {
const categoryList = [];
let category;
if (parentId == null) {
category = categories.filter(cat => cat.parent_id == null);
} else {
category = categories.filter(cat => String(cat.parent_id) == String(parentId));
}
for (let cate of category) {
categoryList.push({
_id: cate._id,
name: cate.name,
slug: cate.slug,
children: nestedCategories(categories, cate._id)
})
}
return categoryList;
}
Upvotes: 3
Reputation: 13588
If you want unlimited nested category you will only need one single category schema.
let schema = new mongoose.Schema(
{
user: ref('user'),
name: { ...rs, unique: true },
description: s,
image: s,
parent: { type: mongoose.Schema.Types.ObjectId }, //the parent category
view: {
...n,
default: 0,
},
},
{ timestamps: true }
);
module.exports = mongoose.model('category', schema);
Unfortunately, you cannot use populate
and $lookup
without specifying a specific level, so you need build the tree yourself if you need unlimited nested.
Upvotes: 0