Mr Robot
Mr Robot

Reputation: 897

Express.js - Mongoose multiple or conditions

I have a userSchema i have to search in the user records with a search key word

//userSchema 
const userSchema = new Schema(
    {
        name: String,
        city: String,
        postalCode: Number
    },
    {
        timestamps: true
    }
);

So the API route is localhost:3000/api/v1/search/:key the key can be user name or city or postalCode, based on the key we have to get the results from collection.

this is what i have tried userController

index: async (req, res, next) => {

    const searchKey = req.params.key;

    const searchResult = await User.find({
        $or:[{name: searchKey},{city: searchKey},{postalCode: searchKey}]
    });

    res.status(200).json({
        message: 'query was succesfull',
        data: searchResult
    });
}

if i pass :key as Canada i am getting following error. if i pass :key as 123456 which is postalCode i am getting data

{
    "error": {
        "message": "Cast to number failed for value \"Canada\" at path \"postalCode\" for model \"users\""
    }
}

So how do i make this query more robust so that based on the :key i have to get the data from user model

Looking for much needed help

Thank you.

Upvotes: 0

Views: 1226

Answers (2)

YouneL
YouneL

Reputation: 8351

Because in the userSchema you declared postalCode as type of number, mongoose expect the searchKey to be number, try to build the query condition based on searchKey type:

// if searchKey is number
if ( parseInt(searchKey) ) {
    var condition = { postalCode: searchKey };
} else {
    var condition = { $or:[ { name: searchKey }, { city: searchKey }] };
}

const searchResult = await User.find(condition);

Edit: Use $regex operator if you want to search by Word Similarities, but first you need to change postalCode type to string:

const searchResult = await User.find({
    $or:[ 
        { name: { $regex: new RegExp(searchKey, 'i') } },
        { city: { $regex: new RegExp(searchKey, 'i') } },
        { postalCode: { $regex: new RegExp(searchKey, 'i') } }
    ]
});

Upvotes: 1

ViKiG
ViKiG

Reputation: 783

Try:

{postalCode: isNaN(parseInt(searchKey)) ? undefined : parseInt(searchKey)}

Upvotes: 1

Related Questions