hi guys with queries or aggregation i have tried to get my data to the front end.
the response is always like this
{
categoryName: ‘Starters/Appetizers’,
categoryOrderId: 1,
isCategoryPublic: true,
items:
},
{
categoryName: ‘Salads’,
categoryOrderId: 2,
isCategoryPublic: true,
items: [Array]
},
this is the schema
mport { Schema, model, models, Document, Types, Model } from “mongoose”;
// Menu schema
const ColorsSchema = new Schema(
{
menuBgColor: { type: String, default: “fff” },
menuTextColor: { type: String, default: “000” },
menuTitleColor: { type: String, default: “000” },
menuCategoriesTitleColor: { type: String, default: “000” },
},
{ _id: false } // ← disable _id
);
export interface IMenuItem extends Document {
itemName: string;
itemDescription: string;
categoryName: string;
itemOrder: number;
itemPrice: number;
isMenuItemPublic: boolean;
itemPicUrl:string
}
const MenuItemSchema = new Schema(
{
itemName: { type: String },
itemDescription: { type: String },
itemOrder: { type: Number },
itemPrice: { type: Number },
isMenuItemPublic: { type: Boolean, default: true },
categoryName: {
type: String,
},
itemPicUrl:{type:String}
},
{
timestamps: true,
_id: false,
}
);
export interface IMenuCategories extends Document {
categoryName: string;
categoryOrderId: number;
isCategoryPublic: boolean;
items: (typeof MenuItemSchema);
menu_id: Schema.Types.ObjectId;
}
const MenuCategoriesSchema = new Schema(
{
// createdAt: { type: Date, default: Date.now },
categoryName: { type: String },
categoryOrderId: { type: Number },
isCategoryPublic: { type: Boolean, default: true },
items: [
{
type: MenuItemSchema,
},
],
menu_id: {
type: Schema.Types.ObjectId,
ref: “MenuSchema”,
index: true,
required: true,
},
},
{
timestamps: true,
}
);
// Define TypeScript interfaces
export interface IMenu extends Document {
menuName: string;
colors: Types.ObjectId;
isPdfPublic: boolean;
menuPdfs?: Schema.Types.ObjectId;
menuCategories?: Schema.Types.ObjectId;
}
const MenuSchema = new Schema(
{
// createdAt: { type: Date, default: Date.now },
menuName: { type: String },
colors: {
type: ColorsSchema,
},
isPdfPublic: { type: Boolean, default: false },
menuCategories: [{ type: Schema.Types.ObjectId, ref: “MenuCategory” }],
menuPdf: { type: Schema.Types.ObjectId, ref: “MenuPdf” },
entity_id: {
type: Schema.Types.ObjectId,
ref: “Entity”,
index: true,
required: true,
},
},
{
timestamps: true,
}
);
and this is the api that gets me the data without the nested array of items.
const menu = await Menu.aggregate([
{
// Match the menu by entity_id
$match: { _id: new Types.ObjectId(menuId) },
},
{
// Lookup menuCategories collection based on the array of category ids
$lookup: {
from: “menucategories”, // Name of the MenuCategories collection
localField: “menuCategories”, // Reference array in the Menu collection
foreignField: “_id”, // Foreign field in the MenuCategories collection
as: “menuCategories” // Alias for the populated field
}
},
{
// Project the required fields: include menuCategories with nested items
$project: {
menuName: 1, // Keep menuName
"menuCategories.categoryName": 1,
"menuCategories.categoryOrderId": 1,
"menuCategories.isCategoryPublic": 1,
"menuCategories.items": 1 // Include populated items
}
}
]);
any advice will be welcome