skip to Main Content

I am stuck at fetching categorized posts via mongodb in nextjs app

I have 2 Models One is Post Model and other one is Category Model. I want to make a relation between Post Model and Category Model in such a way that Each Category Should fetch only its relevant Posts.

POST MODEL

import mongoose, { Schema } from "mongoose";

const postSchema = new Schema({
    createdAt : {
        type: Date,
        default: Date.now()
      },
    slug : {type: String, unique:true},
    title:     String,
    desc:      String,
    img:       String,
    views:     {type:Number,       default:0},
    catSlug:   String,
    

    ***cat:       [{type:mongoose.Schema.ObjectId, ref:'Category'}],*** ====> I have tried to connect it but it is not working.

    userEmail: String,
    user: [{type:mongoose.Schema.ObjectId, ref:'User'}],
    tags: [String]
})



const Post = mongoose.models.Post ||mongoose.model("Post", postSchema )

export default Post

CATEGORY MODEL

import mongoose, { Schema } from "mongoose"

const categorySchema = new Schema({
    title: {type:String, required:true},
    slug:{type:String, required:true, unique:true},
    Posts:[{type:mongoose.Schema.ObjectId, ref:'Post'}]
},

{timestamps:true}

)


const Category = mongoose.models.Category ||mongoose.model("Category", categorySchema )

export default Category

ROUTE FOR FETCHING DATA

import Post from "@/app/models/Post"
import ConnectDB from "@/utils/ConnectDB"
import { NextResponse } from "next/server"

export const GET = async (req) => {
    const {searchParams} = new URL(req.url)
    const cat = searchParams.get("cat")
    
    try {
        await ConnectDB()
    
        const posts = await Post.find({ cat }).populate('cat')
        return NextResponse.json({posts},{status:200})
    } catch (error) {
        console.log(error)
        return NextResponse.json({"Msg":"Error fetching Posts by Cat"},{status:500})
        
    }
}

After fetching i got the following error:

"CastError: Cast to ObjectId failed for value "Travel" (type string) at path "cat" for model "Post"

In above Error "Travel" refers to the Category Name i am fetching.

It is probably the problem with Post.find() method.

I am following a tutorial in which the tutor uses prisma but i an not good at prisma either therefore i wanted to do it with MongoDB and React. The Prisma Models are as under:-

model Category {
  slug  String  @unique
  title String
  Posts Post[]
}

model Post {
  createdAt DateTime  @default(now())
  slug      String    @unique
  title     String
  desc      String
  img       String?
  views     Int       @default(0)
  catSlug   String
  cat       Category  @relation(fields: [catSlug], references: [slug])
  userEmail String
  user      User      @relation(fields: [userEmail], references: [email])

}

2

Answers


  1. Chosen as BEST ANSWER

    A Simple match query solved my problem:

      const posts = await Post.aggregate(
            [ { $match : { catSlug : cat } } ]
        );
    

  2. This seems like a query problem.

    const posts = await Post.find({ cat }).populate('cat')
    This will search for { cat: ‘Travel’ }, which won’t work as mongodb expects an ObjectId, to search for ‘Travel’, you should either query Category directly and populate posts from there.

    const categories = await Category.find({ title: 'Travel'}).populate('Post')

    or if you want to query as you have done above then you will need the querying options like match which will match the title of category to what you have searched. you can reference here

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