Reputation: 63
My first post here :)
I'm using Flask and PyMongo for my site and I want the user to have an ability to filter database results. To start simple:
Basic filter would return results based on the price argument. If the price is None then I want to return all the results.
From MongoDB docs:
The $or operator performs a logical OR operation on an array of two or more expressions and selects the documents that satisfy at least one of the expressions
price = request.args.get('price')
if price:
price = int(price)
posts = db.collection.find({ '$or' : [
{'price' : {'$lt' : price }},
{'price' : {'$ne' : None }}
]
})
My idea was that if the price is not an integer (None) that the $or operator wouldn't satisfy first expression and move to the second one returning all that are not equal to None. However this doesn't really work and I can't figure any other way to display 'all' results when the argument is not passed or when it is wrong.
Also a bit borader questions - what if I want to have multiple filters? Should I create one big query for the database using $and operator and manipulate variable values in order to get the desired result? Or is there a better way? The only thing I thought about was a route for each filter but this doesn't sound like something that would work. Any suggestions are welcome! Thank you!
Upvotes: 1
Views: 2081
Reputation: 21
If you want to pass an array from a front end (using query parameters) you can use the $in parameter for mongodb: URL Parameters sent in array as JSON object:
/read?job_type%5B%5D=Full%20Time&job_type%5B%5D=Part%20Time&country%5B%5D=Germany&country%5B%5D=China
@app.route("/read", methods=['GET', 'POST'])
def read():
job_type = request.args.getlist('job_type[]')
country = request.args.getlist('country[]')
filter = {}
if len(job_type) > 0: filter['job_type'] = {'$in': job_type}
if len(country) > 0: filter['country'] = {'$in': country}
jobs = db_operations.find(filter)
Upvotes: 1
Reputation: 8814
EDIT:
For multiple filters:
filter = {}
if price is not None: filter['price'] = {'$lt' : price }
if quantity is not None: filter['quantity'] = {'$lt' : quantity }
if volume is not None: filter['volume'] = {'$lt' : volume }
posts = db.testcollection.find(filter)
ORIGNAL:
Try this to save yourself going slightly mad in the boolean logic world:
if price is None:
filter = {}
else:
filter = {'price' : {'$lt' : price }}
posts = db.collection.find(filter)
Upvotes: 1