mongu
mongu

Reputation: 43

filter mongoose query by year

i need to give the api user the option to filter the wine query by year, but when no year is specified mongoose should not return an empty array same with the price property

http://localhost:1234/api/wine?year=2010 should return wines from 2010

http://localhost:1234/api/wine should return all wines (actually 10, because of the limit)

i was able to implement other filters as you can see below btw, is this the best way to do it?

thank you

controller

  getWines: async (req, res) => {
    try {
      const types = ['red', 'white'];
      let {
        limit = 10,
        page = 1,
        // sort = 'asc',
        search = '',
        type = 'all',
        year = undefined,
      } = req.query;
      if (page === '0') {
        return res.json({ error: 'Invalid page' });
      }
      type === 'all' ? (type = [...types]) : (type = [req.query.type]);
      const response = await Wine.find({
        name: { $regex: search, $options: 'i' },
      })
        .where('type')
        .in(type)
        // .where('year')
        // .equals(parseInt(year))
        // .sort(sort)
        .limit(limit)
        .skip((parseInt(page) - 1) * limit);
      res.json(response);
    } catch (error) {
      console.error(error);
    }
  },

documents sample

[{
"_id": "63952372129acf895c427240",
        "name": "Chateau Leoville Barton",
        "year": 2010,
        "type": "red",
        "domain": "Saint-Julien",
        "quantity": 750,
        "price": 169,
        "quality": 100,
        "image": <<<<LONG_URL>>>>
},
{
        "_id": "639523e7129acf895c42c238",
        "name": "Chateau La Mission Haut Brion",
        "year": 2014,
        "type": "red",
        "domain": "Pessac-Leognan",
        "quantity": 750,
        "price": 219,
        "quality": 94,
        "image": <<<<LONG_URL>>>>
}]

Upvotes: 0

Views: 210

Answers (1)

hoangdv
hoangdv

Reputation: 16137

Just create a filter object base on name and type conditions, if req.query.year exists then add an additional condition.

const conditions = {
  name: { $regex: search, $options: 'i' },
  type: { $in: types },
};

if (year) {
  conditions.year = parseInt(year);
}

const response = await Wine.find(conditions)
  .limit(limit)
  .skip((parseInt(page) - 1) * limit);

Upvotes: 2

Related Questions