简体   繁体   中英

$gte & $lte is not working as expected in Mongoose/MongoDB

I am filtering product list by price range. Some price range works fine and some doesn't. When I clicked (radio box) the price range in frontend, it gets processed in the backend via the pricelist. It looks like $gte and $lte not working as expected. Am I missing anything?

react frontend ---- pricelist:

export const prices = [
    {
        _id:0,
        name: 'Any',
        array: []
    },
    {
        _id:1,
        name: '$50 to $99',
        array: [50, 99]
    },
    {
        _id:2,
        name: '$100 to $199',
        array: [100, 199]
    },
    {
        _id:3,
        name: '$200 to $299',
        array: [200, 299]
    },
    {
        _id:4,
        name: '$300 to $399',
        array: [300, 399]
    },
    {
        _id:5,
        name: '$400 to $599',
        array: [400, 599]
    },
    {
        _id:6,
        name: '$600 to $799',
        array: [600, 799]
    },
]

NodeJS Backend -------- Product Search List:

exports.listBySearch = (req, res) => {
    let order = req.body.order ? req.body.order : "desc";
    let sortBy = req.body.sortBy ? req.body.sortBy : "_id";
    let limit = req.body.limit ? parseInt(req.body.limit) : 100;
    let skip = parseInt(req.body.skip);
    let findArgs = {};

    // console.log(order, sortBy, limit, skip, req.body.filters);
    // console.log("findArgs", findArgs);

    for (let key in req.body.filters) {
        if (req.body.filters[key].length > 0) {
            if (key === "price") {
                // gte -  greater than price [0-10]
                // lte - less than
                findArgs[key] = {
                    $gte: req.body.filters[key][0],
                    $lt: req.body.filters[key][1]
                };
                console.log(findArgs)
               // console.log -- { price: { '$gte': 50, '$lt': 99.99 } }
            } else {
                findArgs[key] = req.body.filters[key];
            }
        }
    }

    Product.find(findArgs)
        .select("-images")
        .populate("category")
        .sort([[sortBy, order]])
        .skip(skip)
        .limit(limit)
        .exec((err, data) => {
            if (err) {
                return res.status(400).json({
                    error: "Products not found"
                });
            }
            res.json({
                size: data.length,
                data
            });
        });
};

Mongoose --------- DB:

{
    "_id" : ObjectId("6079a8d675db7021c00aa973"),
    "sold" : 5,
    "name" : "Java Book for Everyone",
    "description" : "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
    "price" : "75",
    "category" : ObjectId("605c9c94dcf90b34e8ec33e0"),
    "shipping" : false,
    "quantity" : 7,
    "createdAt" : ISODate("2021-04-16T15:10:14.626Z"),
    "updatedAt" : ISODate("2021-04-16T15:10:14.626Z"),
    "__v" : 0
}

The price inside the mongoDB document is of type string . That's why query doesn't work. You want to cast the value of price inside mongo to number in order to compare. Modify the query to send something like this:

 { $expr: { $and: [ $gte: [{ $toDouble: "$price" }, req.body.filters[key][0]], $lt: [{ $toDouble: "$price" }, req.body.filters[key][1]] ] } }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM