skip to Main Content

I have two collections Categories and Subcategories inside a Categories collection. I have an array that is storing the ids of subcategories that are stored in Subcategories collection. Below is my document structure:

Categories collection

{
  id:65,
  title:"Automotive",
  active:true,
  subcategories:[35,28,30]
}

subcategories collection

{
  id:35,
  title:"Automotive technology",
  category_id:65,
  active:true
},
{
  id:28,
  title:"Automotive coatings",
  category_id:65,
  active:true
},
{
  id:30,
  title:"Machinery and equipments",
  category_id:65,
  active:true
}  

As seen in above collection 3 documents from subcategories collection have been associated with the category document. I want to fetch data in below format on single API hit.

API response should be in below format:

{
 data:{
     category:{
               id:65,
               title:"Automotive",
               subcategories:[{
                                id:35, 
                                name:"Automotive technology",
                              },
                              {
                                id:28, 
                                name:"Automotive coatings",
                              },
                              {
                                id:30, 
                                name:"Machinery and equipments",
                             }]
              },
     category:{
                 id:66,
                 title:"Food",
                 subcategories:[{
                                 id:23, 
                                 name:"Drinks",
                                },
                                {
                                 id:2, 
                                 name:"Additives",
                               }]
               },
   },
   messsage:"Success",
   code:200
}

As of now I am able to get data in 2 api hits that is like first getting all the categories

 const category = await db.categories.find({});

Then on click of some particular category fetching all the sub categories based on the category id.

const subCategories = await db.SubCategories.find({category_id:id});   

How can I get the above data in desired format in single API hit?

2

Answers


  1. You need something like this, also, if you use mongoose, you can use .populate()

    To format data you can use $project stage in aggregation pipeline or projection in .find()

    Login or Signup to reply.
  2. If you want to use Mongoose with populate:

    CategorySchema:

    const CategorySchema= new mongoose.Schema({
      ...
      subCategories: [{ type: mongoose.Schema.Types.ObjectId, ref: 'SubCategory' }],
      ...
    });
    
    
    • need _id column on reference table

    • ref content is must be equal to model name like

      module.exports = mongoose.model('SubCategory', SubCategorySchema);
      

    Controller:

    const categories = await Category.find({})
      .populate({
        path: 'subCategories'
      })
    
    • path content is must be equal to column name

    If you want to write with Mongo query:

    db.getCollection("categories").aggregate([
        {
           $lookup:
             {
                 from: 'subCategories',
                 localField: 'subCategories',
                 foreignField: 'id',
                 as: 'subCategories'
             }
        }
    ])
    

    You get empty object because you are not using "_id" field for join schemas. If you want to use "id" field u need to use virtuals on Mongoose:

    https://mongoosejs.com/docs/tutorials/virtuals.html#populate

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search