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
A Simple match query solved my problem:
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