Search code examples
javascriptmongodbmongoose

Mongoose .find() with multiple conditions, getting cast error using Javascript


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);


Solution

  • Since the comment fixed the issue, I added it as the answer.

    Seems the router interprets the path /search as value, 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.