leodinas-hao / mongoose-query-parser

Convert url query string to MongooseJs friendly query object including advanced filtering, sorting, population, string template, type casting and many more...
MIT License
68 stars 17 forks source link

Work with Mongoose #6

Closed Damien2k9 closed 4 years ago

Damien2k9 commented 5 years ago

Hi leodinas

I'm having trouble working with Mongoose and its package. I wanted an example of how I can sort by various categories.

my code:

router.get('/products/:page', function(req, res, next){
    const perPage = 15;
    var page = req.params.page || 1;
    var sortBy = req.query.sortBy || 'name';
    var order = req.query.order || 'asc';

    Product
        .find({})
        .sort({name: 'asc'})
        .skip((perPage * page) - perPage)
        .limit(perPage)
        .exec(function(err, products){
            Product.countDocuments().exec(function(err, count){
                if(err) return next(err)
                res.render('products', {
                    products: products,
                    current: page,
                    pages: Math.ceil(count / perPage)
                });
                //console.log("Sort: " + sortBy + " Order: " + order);
            });
        });
});

In the code I created 2 variables to try to sort but it is not working and I would like to use your package, but I don't know how to implement it in my code, can you help me?

Thanks

Damien2k9 commented 5 years ago

Hi again

Now I recived this error when I start the server....

import { MongooseQueryParser } from 'mongoose-query-parser';
       ^

SyntaxError: Unexpected token {
    at Module._compile (internal/modules/cjs/loader.js:720:22)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:788:10)
    at Module.load (internal/modules/cjs/loader.js:643:32)
    at Function.Module._load (internal/modules/cjs/loader.js:556:12)
    at Module.require (internal/modules/cjs/loader.js:683:19)
    at require (internal/modules/cjs/helpers.js:16:16)
    at Object.<anonymous> (C:\xampp\htdocs\acma\server.js:20:24)
    at Module._compile (internal/modules/cjs/loader.js:777:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:788:10)
    at Module.load (internal/modules/cjs/loader.js:643:32)
    at Function.Module._load (internal/modules/cjs/loader.js:556:12)
    at Function.Module.runMain (internal/modules/cjs/loader.js:840:10)
    at internal/main/run_main_module.js:17:11

My Code:

import { MongooseQueryParser } from 'mongoose-query-parser';

const parser = new MongooseQueryParser();

router.get('/products/:page', function(req, res, next){
    const perPage = 15;
    var page = req.params.page || 1;

    parser.parse('sort=name');

    Product
        .find({})
        .sort(parser)
        .skip((perPage * page) - perPage)
        .limit(perPage)
        .exec(function(err, products){
            Product.countDocuments().exec(function(err, count){
                if(err) return next(err)
                res.render('products', {
                    products: products,
                    current: page,
                    pages: Math.ceil(count / perPage)
                });
                //console.log("Sort: " + sortBy + " Order: " + order);
            });
        });
});

Help-me please.... Thanks

leodinas-hao commented 4 years ago

Hi, @Damien2k9 this query parser only helps parse string to a formatted query object. Then you can use the query object to carry out your query executions. An example like below:

import { MongooseQueryParser } from 'mongoose-query-parser';

const qry = new MongooseQueryParser().parse('sort=name');

// then do you query on your model like following
Product.find(qry.filter || {}).sort(filter.sort);

Or the better way can be add the following extensions to mongoose

function query<T extends Mongoose.Document>(queryOptions: QueryOptions): Promise<T[]> {
  const model = this as Mongoose.Model<T>;

  let chain = model.find(queryOptions.filter || {});
  if (queryOptions.populate) {
    chain = chain.populate(queryOptions.populate);
  }
  if (queryOptions.sort) {
    chain = chain.sort(queryOptions.sort);
  }
  if (queryOptions.limit) {
    chain = chain.limit(queryOptions.limit);
  }
  if (queryOptions.skip) {
    chain = chain.skip(queryOptions.skip);
  }
  if (queryOptions.select) {
    chain = chain.select(queryOptions.select);
  }

  return chain.exec();
}
Mongoose.Model.query = query;

Then you can do query like

router.get('/', (req: Request, res: Response, next: NextFunction) => {
  try {
    const qry = new MongooseQueryParser().parse(req.query);
    YourModel.query(qry).then((orders) => {
      // handle your results
     // ...
    }).catch((err) => {
      next(err);  // failed to query db
    });
  } catch (err) {
    // failed to parse req.query -> invalid user input
    next(new HttpError(422, err));
  }
});