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 = request.args.get("page", default=1, type=int)
|
||||||
page_size = request.args.get("page_size", default=10, 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)
|
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:
|
except Exception as e:
|
||||||
return make_error_response(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
|
author_id: Optional[str] = None
|
||||||
title: str
|
title: str
|
||||||
description: Optional[str] = None
|
description: Optional[str] = None
|
||||||
subject: str
|
# subject: str
|
||||||
is_public: bool = False
|
is_public: bool = False
|
||||||
date: Optional[datetime] = None
|
date: Optional[datetime] = None
|
||||||
total_quiz: Optional[int] = 0
|
total_quiz: Optional[int] = 0
|
||||||
|
|
|
@ -21,6 +21,68 @@ class QuizRepository:
|
||||||
return QuizEntity(**data)
|
return QuizEntity(**data)
|
||||||
return None
|
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]]:
|
def get_by_ids(self, quiz_ids: List[str]) -> Optional[List[QuizEntity]]:
|
||||||
object_ids = [ObjectId(qid) for qid in quiz_ids]
|
object_ids = [ObjectId(qid) for qid in quiz_ids]
|
||||||
cursor = self.collection.find({"_id": {"$in": object_ids}})
|
cursor = self.collection.find({"_id": {"$in": object_ids}})
|
||||||
|
|
|
@ -19,6 +19,37 @@ class QuizService:
|
||||||
raise DataNotFoundException("Quiz not found")
|
raise DataNotFoundException("Quiz not found")
|
||||||
return map_quiz_entity_to_schema(data)
|
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(
|
def get_user_quiz(
|
||||||
self, user_id: str, page: int = 1, page_size: int = 10
|
self, user_id: str, page: int = 1, page_size: int = 10
|
||||||
) -> UserQuizListResponse:
|
) -> UserQuizListResponse:
|
||||||
|
|
Loading…
Reference in New Issue