feat: search quiz done
This commit is contained in:
parent
ad00d2b9de
commit
89deae92b3
|
@ -59,3 +59,12 @@ def get_user_quiz(
|
|||
page = request.args.get("page", default=1, type=int)
|
||||
page_size = request.args.get("page_size", default=10, type=int)
|
||||
return controller.get_user_quiz(user_id=user_id, page=page, page_size=page_size)
|
||||
|
||||
|
||||
@quiz_bp.route("/search", methods=["GET"])
|
||||
@inject
|
||||
def search_quiz(controller: QuizController = Provide[Container.quiz_controller]):
|
||||
keyword = request.args.get("keyword", "")
|
||||
page = int(request.args.get("page", 1))
|
||||
limit = int(request.args.get("limit", 10))
|
||||
return controller.search_quiz(keyword=keyword, page=page, limit=limit)
|
||||
|
|
|
@ -127,3 +127,10 @@ class QuizController:
|
|||
)
|
||||
except Exception as e:
|
||||
return make_error_response(e)
|
||||
|
||||
def search_quiz(self, keyword: str, page: int, limit: int):
|
||||
try:
|
||||
result = self.quiz_service.search_quiz(keyword, page, limit)
|
||||
return make_response(message="success", data=result)
|
||||
except Exception as e:
|
||||
return make_error_response(e)
|
||||
|
|
|
@ -10,7 +10,7 @@ class QuizEntity(BaseModel):
|
|||
author_id: Optional[str] = None
|
||||
title: str
|
||||
description: Optional[str] = None
|
||||
subject: str
|
||||
# subject: str
|
||||
is_public: bool = False
|
||||
date: Optional[datetime] = None
|
||||
total_quiz: Optional[int] = 0
|
||||
|
|
|
@ -21,6 +21,68 @@ class QuizRepository:
|
|||
return QuizEntity(**data)
|
||||
return None
|
||||
|
||||
# def search_by_title_or_category(
|
||||
# self, keyword: str, page: int, page_size: int
|
||||
# ) -> List[QuizEntity]:
|
||||
# skip = (page - 1) * page_size
|
||||
# pipeline = [
|
||||
# {
|
||||
# "$lookup": {
|
||||
# "from": "category",
|
||||
# "localField": "category_id",
|
||||
# "foreignField": "_id",
|
||||
# "as": "category_info",
|
||||
# }
|
||||
# },
|
||||
# {"$unwind": "$category_info"},
|
||||
# {
|
||||
# "$match": {
|
||||
# "$or": [
|
||||
# {"title": {"$regex": keyword, "$options": "i"}},
|
||||
# {"category_info.name": {"$regex": keyword, "$options": "i"}},
|
||||
# ]
|
||||
# }
|
||||
# },
|
||||
# {"$skip": skip},
|
||||
# {"$limit": page_size},
|
||||
# ]
|
||||
# cursor = self.collection.aggregate(pipeline)
|
||||
# return [QuizEntity(**doc) for doc in cursor]
|
||||
|
||||
def search_by_title_or_category(
|
||||
self, keyword: str, page: int, page_size: int
|
||||
) -> List[QuizEntity]:
|
||||
skip = (page - 1) * page_size
|
||||
cursor = (
|
||||
self.collection.find(
|
||||
{
|
||||
"$and": [
|
||||
{"is_public": True},
|
||||
{
|
||||
"$or": [
|
||||
{"title": {"$regex": keyword, "$options": "i"}},
|
||||
# {"category": {"$regex": keyword, "$options": "i"}},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
.skip(skip)
|
||||
.limit(page_size)
|
||||
)
|
||||
|
||||
return [QuizEntity(**doc) for doc in cursor]
|
||||
|
||||
def count_by_search(self, keyword: str) -> int:
|
||||
return self.collection.count_documents(
|
||||
{
|
||||
"$or": [
|
||||
{"title": {"$regex": keyword, "$options": "i"}},
|
||||
{"category": {"$regex": keyword, "$options": "i"}},
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
def get_by_ids(self, quiz_ids: List[str]) -> Optional[List[QuizEntity]]:
|
||||
object_ids = [ObjectId(qid) for qid in quiz_ids]
|
||||
cursor = self.collection.find({"_id": {"$in": object_ids}})
|
||||
|
|
|
@ -19,6 +19,37 @@ class QuizService:
|
|||
raise DataNotFoundException("Quiz not found")
|
||||
return map_quiz_entity_to_schema(data)
|
||||
|
||||
def search_quiz(
|
||||
self, keyword: str, page: int = 1, page_size: int = 10
|
||||
) -> tuple[list[RecomendationResponse], int]:
|
||||
if not keyword:
|
||||
raise ValidationException("Keyword cannot be empty.")
|
||||
|
||||
quizzes = self.quiz_repository.search_by_title_or_category(
|
||||
keyword, page, page_size
|
||||
)
|
||||
total = self.quiz_repository.count_by_search(keyword)
|
||||
print("quiz len", len(quizzes))
|
||||
mapped_quizzes = []
|
||||
for quiz in quizzes:
|
||||
author = self.user_repostory.get_user_by_id(user_id=quiz.author_id)
|
||||
if author is None:
|
||||
print(quiz.author_id, "skipped")
|
||||
continue # or handle default name
|
||||
|
||||
mapped_quizzes.append(
|
||||
RecomendationResponse(
|
||||
quiz_id=str(quiz.id),
|
||||
author_id=str(author.id),
|
||||
author_name=author.name,
|
||||
title=quiz.title,
|
||||
description=quiz.description,
|
||||
date=quiz.date.strftime("%d-%B-%Y"),
|
||||
)
|
||||
)
|
||||
|
||||
return mapped_quizzes, total
|
||||
|
||||
def get_user_quiz(
|
||||
self, user_id: str, page: int = 1, page_size: int = 10
|
||||
) -> UserQuizListResponse:
|
||||
|
|
Loading…
Reference in New Issue