Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optional parameters in MongoDB

I am working with Node Js and Express, I make the queries to MongoDB through Mongoose. I am having trouble with a get request that can receive 3 optional parameters.

For example:

http://localhost:3000/transactions/?dateFrom=2019-01-01&dateTo=2020-07-07&account=1234

The query in mongoDB would be like this in the case of receiving all the parameters, it works fine:

const transaction = await Transfer.find ({date: {$ gte: dateFrom, $ lte: dateTo}, accountFrom: accountID} {date: {$ gte: dateFrom, $ lte: dateTo}, accountFrom: accountID});

My problem is that I can receive 1, 2, or 3 parameters and the query would change. I have a way to tell mongo not to take a parameter into account if it is undefined?

My complete code (works but it's a horror!). If there were 10 optional parameters it would be impossible to do this:

router.get('/', async (req, res) => {

    let dateFrom = req.query.dateFrom;
    let dateTo = req.query.dateTo;
    let accountID = req.query.accountID;
    let query;

    if (typeof dateFrom != 'undefined' && typeof dateTo != 'undefined' && typeof accountID != 'undefined') query = { date: { $gte: dateFrom, $lte: dateTo }, accountFrom: accountID };
    if (typeof dateFrom != 'undefined' && typeof dateTo != 'undefined' && typeof accountID == 'undefined') query = { date: { $gte: dateFrom, $lte: dateTo } };
    if (typeof dateFrom != 'undefined' && typeof dateTo == 'undefined' && typeof accountID != 'undefined') query = { date: { $gte: dateFrom }, accountFrom: accountID };
    if (typeof dateFrom == 'undefined' && typeof dateTo != 'undefined' && typeof accountID != 'undefined') query = { date: { $lte: dateTo }, accountFrom: accountID };
    if (typeof dateFrom != 'undefined' && typeof dateTo == 'undefined' && typeof accountID == 'undefined') query = { date: { $gte: dateFrom }};
    if (typeof dateFrom == 'undefined' && typeof dateTo != 'undefined' && typeof accountID == 'undefined') query = { date: { $lte: dateTo }};
    if (typeof dateFrom == 'undefined' && typeof dateTo == 'undefined' && typeof accountID != 'undefined') query = { accountFrom: accountID };

    const transaction = await Transfer.find({ date: { $gte: dateFrom, $lte: dateTo }, accountFrom: accountID }{ date: { $gte: dateFrom, $lte: dateTo }, accountFrom: accountID });

    if (!transaction) return res.status(404).send('The transaction with the given ID was not found.');

    res.send(transaction);
});

The explanation was a bit long but I wanted to give all the context.

Thanks so much for any help!

like image 288
Mauricio De Oliveira Avatar asked Apr 09 '26 21:04

Mauricio De Oliveira


1 Answers

There's no work around that avoids using custom logic, but we can make it a little more read-able and scaleable by utilizing Mongo's built in boolean operators like $and. By doing so we can avoid checking every single permutation and just construct the conditions as we go.

router.get('/', async (req, res) => {

    let dateFrom = req.query.dateFrom;
    let dateTo = req.query.dateTo;
    let accountID = req.query.accountID;
    
    let conditions = [];
    if (!!dateFrom) {
        conditions.push({date: {$gte: dateFrom}});
    }
    if (!!dateTo) {
        conditions.push({date: {$lte: dateFrom}});
    }

    if (!!accountID) {
        conditions.push({accountFrom: accountID});
    }

    let final_condition = conditions.length ? {$and: conditions} : {};
    const transaction = await Transfer.find(final_condition);

    if (!transaction) return res.status(404).send('The transaction with the given ID was not found.');

    res.send(transaction);
});
like image 189
Tom Slabbaert Avatar answered Apr 12 '26 09:04

Tom Slabbaert



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!