alfredopacino
alfredopacino

Reputation: 3241

perform a mongoose query in querystring

I'm trying to do a simple mongoose query using the query string. This works

router.get('/', function(req,res) {
    myModel.find({name:"test e"}, function(err,data){
        if(err) console.log(err)
        res.json(data);
    });

});

This doesn't work (I get the whole collection)..

router.get('/', function(req,res) {
    console.log(req.query.q)
    myModel.find(req.query.q, function(err,data){
        if(err) console.log(err)
        res.json(data);
    });

});

with this request

/api/myModel?q={name:"test e"}

I don't think it's an url encoding issue since I print the 'q' var and it looks fine server side.

Side question: if this isn't the standard mode, what's the RESTful standard way to query a db?

Edit for more general details: I don't need a simple access by id or name like Ashley B suggests, I need a proper search engine for my db (the user, using a graphic web interface, have to be able to query each field separately, potentially)

Edit 2: thanks to Blakes Seven I solved my initial problem, but if you know or use a better way to perform a complex query I would happy to discuss. Maybe I should expose anther resource "/api/seach"?

Upvotes: 4

Views: 14164

Answers (3)

Diego Haz
Diego Haz

Reputation: 938

I would recommend you to use some library to parse the querystrings to mongoDB queries. It would fix your problem and make your code better.

querymen would help you by transforming /myModel?q=test+e into {name: 'test e'}, giving you full control over the querystring schema.

var querymen = require('querymen')

// querymen.middleware() defines an express middleware with querystring schema
router.get('/', querymen.middleware({
  q: {
    type: String,
    paths: ['name']
  }
}), function(req, res) {
  console.log(req.querymen.query) // {name: 'test e'}
  myModel.find(req.querymen.query, function(err,data){
    if(err) console.log(err)
    res.json(data);
  });
});

Upvotes: 3

Ash
Ash

Reputation: 6783

I think I can answer your first question by answering your second (side question).

Let's say you have a User model, normally you'd have an endpoint to get all users, like so:

router.get('/users', function(req, res) {
    // find all users
    users.find({}, function(err, data){
        if(err) console.log(err)
        res.json(data);
    });
});

To find a specific user you then have an endpoint like so:

router.get('/users/:name', function(req, res) {
    // get the user's name from the url and find that user
    users.find({name: req.params.name}, function(err, data){
        if(err) console.log(err)
        res.json(data);
    });
});

So rather than passing the whole query through the query string, you just find use a specific part. Allowing the users to directly access your data with their own queries makes it much much harder to secure.

Upvotes: 3

Patryk Wojtasik
Patryk Wojtasik

Reputation: 431

The proper query should look like this:

/api/myModels?name=test%20e

The myModals part is in plural.

Check here: How to design RESTful search/filtering?

Upvotes: 0

Related Questions