Ludwig Goohsen
Ludwig Goohsen

Reputation: 111

How to write Mongoose Queries with optional express query-params?

I am building a REST API on top of Express 4. For a path lets say GET /api/users I want to query my users collection accordingly to optional queryParams.

So a call to the API could look like this host:port/api/users?city=Berlin

In this case name is omitted and doesn't influence the query, whereas city has to match.

I managed to do this with the following hack. Is there a better way than that?

Users.statics.customFilter = function(qP){
    return this.find({
        $and: [
            {$or: [{undefined: {$eq: qP.city}}, {'city': qP.city}]},
            {$or: [{undefined: {$eq: qP.name}}, {'name': qP.name}]}
        ]
    });

mongoose.model('User', Users);

I'm calling this static function from the mongoose schema like this...

const User = mongoose.model('User');
app.get('/api/users', (req, res) => {
        User.customFilter(req.query)
        .exec((err, results) => {
            if (err) return next(err);
            res.json(results);
        });
    });

Upvotes: 2

Views: 15235

Answers (2)

maya
maya

Reputation: 1

Because I couldn't find the answer, I will show you how I solved it. I get the parameters from the req.query object. Here I add 2 more queries, that should be always there in my case.

const query = {...req.query, surveyID: id_s, surveyEntityID: id_e};

Then I use mongoose:

let allAnswers = await Answer.find(query);

Upvotes: 0

robertklep
robertklep

Reputation: 203304

It seems to me that in essence, User.find(req.query) should do what you want:

/api/users?city=Berlin           → User.find({ city : 'Berlin' })
/api/users?name=John             → User.find({ name : 'John' })
/api/users?name=John&city=Berlin → User.find({ city : 'Berlin', name : 'John' })

Of course, you have to decide what should happen if no parameters are passed (in the example above, it would become a query that would match all users, which may not be what you want).

Also, you should probably filter req.query so it only contains fields that are defined in your schema.

Upvotes: 9

Related Questions