I am trying to form a search query with mongoose.find() but I keep getting an error back and I am not sure why. It receives a query parameter and return the items whose name OR description contain the parameter.
Here is the code for the search function:
const searchQuery = async (q) => {
try {
const menuItems = await MenuItems.find({
$or: [
{ name: { $regex: q, $options: "i" } },
{ description: { $regex: q, $options: "i" } }
]
});
return menuItems;
} catch (error) {
return error;
}
};
Here is how information is being passed:
const searchQuery = async (req, res) => {
try {
const menu = await MenuItems.searchQuery(req.query.q);
res.send(menu);
} catch (error) {
res.status(500).send(error);
}
};
I am testing/calling it by the route "/api/menu/search?q=pizza" as a get request in postman and I keep getting this error:
{
"stringValue": ""search"",
"valueType": "string",
"kind": "ObjectId",
"value": "search",
"path": "_id",
"reason": {},
"name": "CastError",
"message": "Cast to ObjectId failed for value "search" (type string) at path "_id" for model "MenuItems""
}
code for menuItems:
const menuItemsSchema = new mongoose.Schema({
name: {
type: String,
required: true,
unique: true
},
price: {
type: Number,
required: true
},
description: {
type: String,
required: true
},
imageUrl: {
type: String
},
updatedAt: {
type: Date,
default: Date.now
}
});
menuItemsSchema.set("toJSON", {
virtuals: true
});
// menu model
const MenuItems = mongoose.model("MenuItems", menuItemsSchema);
2
Answers
Since the comment fixed the issue, I added it as the answer.
Seems the router interprets the path
/search
asvalue
, You probably have another route something like/api/menu/:id
where the router takes/search
as the value of:id
.You have to change the order since the routes are being resolved in top-to-bottom order.
Add the
/api/menu/search
router before/api/menu/:id
.The error you are encountering is due to the fact that Mongoose is trying to cast the
q
parameter as an ObjectId because it’s being treated as if you are trying to find a document by its_id
field. To resolve this issue, you should make sure thatq
is properly passed as a query parameter and that yoursearchQuery
function is correctly handling it.Here’s the corrected code for your
searchQuery
function:The issue here seems to be in how you are calling the
searchQuery
function in your route handler. You should pass thereq.query.q
parameter to the function, not try to access it as a property of theMenuItems
model. Here’s the corrected route handler:Make sure that your route is also defined correctly:
With these changes, your route handler will correctly call the
searchQuery
function with theq
query parameter, and the error should be resolved. Now, you should be able to call the route "/api/menu/search?q=pizza" without encountering the ObjectId casting error.