Skip to content

Commit

Permalink
[Search🔍] Implemented a simple search algo for recipes
Browse files Browse the repository at this point in the history
  • Loading branch information
[esekyi] committed Sep 7, 2024
1 parent 5b30286 commit 11df8e4
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 27 deletions.
23 changes: 22 additions & 1 deletion app/routes/search_routes.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@
from flask import Blueprint, request, render_template
from app.services.search_service import search_recipes

search_bp = Blueprint('search', __name__)
search_bp = Blueprint('search', __name__)


@search_bp.route('/search', methods=['GET'], strict_slashes=False)
def search():
query = request.args.get('q', '').strip()
page = int(request.args.get('page', 1))
per_page = int(request.args.get('per_page', 10))

if not query:
return render_template('search_results.html', query=query, recipes=[])

results = search_recipes(query, page, per_page)

return render_template(
'search_results.html',
query=query,
recipes=results['items'],
total_pages=results['total_pages'],
current_page=results['current_page'],
per_page=results['per_page'],
)
40 changes: 15 additions & 25 deletions app/services/search_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,29 @@
from app.models.ingredient import Ingredient
from app.models.instruction import Instruction
from app.models.user import User
from app.services.pagination_service import paginate
from sqlalchemy import or_


def search_recipes(query):
def search_recipes(query, page=1, per_page=10):
"""
Search for recipes based on a query string.
The query can match recipe names, ingredients, author or categories.
"""
query = f"%{query.lower()}%"

# Search by title
recipes_by_title = Recipe.query.filter(Recipe.title.ilike(query)).all()

# Search by description
recipes_by_description = Recipe.query.filter(
Recipe.description.ilike(query)).all()
recipes = Recipe.query.join(Ingredient).join(Category).join(User).filter(
or_(
Recipe.title.ilike(query),
Recipe.description.ilike(query),
Ingredient.name.ilike(query),
Category.name.ilike(query),
User.first_name.ilike(query),
User.last_name.ilike(query),
User.username.ilike(query)
)
).distinct()

# Search by ingredients
recipes_by_ingredient = db.session.query(Recipe).join(
Ingredient).filter(Ingredient.name.ilike(query)).all()

# Search by category name
recipes_by_category = db.session.query(Recipe).join(
Category).filter(Category.name.ilike(query)).all()

# Search by author (first name, last name or username)
author_recipes = db.session.query(Recipe).join(User).filter(
(User.first_name.ilike(query)) |
(User.last_name.ilike(query)) |
(User.username.ilike(query))
).all()

# calling a set function on it to remove duplicates
all_recipes = set(recipes_by_title + recipes_by_category +
recipes_by_description + recipes_by_ingredient + author_recipes)

return list(all_recipes)
return paginate(recipes.all(), page, per_page)
Loading

0 comments on commit 11df8e4

Please sign in to comment.