Skip to content

Commit

Permalink
Merge pull request #691 from bounswe/backend/feature/689/sort-questio…
Browse files Browse the repository at this point in the history
…ns-by-users-followed

[Backend] Sort Questions by Followed Users
  • Loading branch information
ozdentarikcan authored Dec 16, 2024
2 parents e639be8 + 0cc94c6 commit 79eb06b
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,10 @@ public ResponseEntity<GenericApiResponse<Map<String, Object>>> searchQuestions(
@RequestParam(required = false) String tags,
@RequestParam(required = false) DifficultyLevel difficulty,
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "20") int pageSize) {
@RequestParam(defaultValue = "20") int pageSize,
@RequestParam(defaultValue = "recommended") String sortBy) {

Page<Question> questionPage = questionService.searchQuestions(query, tags, difficulty, page, pageSize);
Page<Question> questionPage = questionService.searchQuestions(query, tags, difficulty, page, pageSize, sortBy);

List<QuestionSummaryDto> questionSummaries = questionPage.getContent().stream()
.map(QuestionService::mapToQuestionSummary)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ Page<Question> searchQuestions(
@Param("difficulty") DifficultyLevel difficulty,
Pageable pageable);

@Query("SELECT DISTINCT q FROM Question q " +
"LEFT JOIN q.tags t " +
"WHERE (:query IS NULL OR " +
" LOWER(q.title) LIKE LOWER(CONCAT('%', :query, '%')) OR " +
" LOWER(q.questionBody) LIKE LOWER(CONCAT('%', :query, '%'))) " +
"AND (:tagIds IS NULL OR t.id IN :tagIds) " +
"AND (:difficulty IS NULL OR q.difficulty = :difficulty) " +
"ORDER BY " +
" CASE WHEN :authorIds IS NOT NULL AND q.askedBy.id IN :authorIds THEN 1 ELSE 0 END DESC")
Page<Question> searchQuestionsByRecommended(
@Param("query") String query,
@Param("authorIds") List<Long> authorIds,
@Param("tagIds") List<Long> tagIds,
@Param("difficulty") DifficultyLevel difficulty,
Pageable pageable);

@Query("SELECT q FROM Question q WHERE q.askedBy.id = :author")
List<Question> findByAuthorId(@Param("author") Long authorId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.Objects;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
Expand Down Expand Up @@ -218,17 +219,32 @@ public Page<Question> searchQuestions(
String tagIdsStr,
DifficultyLevel difficulty,
int page,
int pageSize) {
int pageSize,
String sortBy) {

List<Long> tagIds = null;
if (tagIdsStr != null && !tagIdsStr.isEmpty()) {
tagIds = Arrays.stream(tagIdsStr.split(","))
.map(Long::parseLong)
.collect(Collectors.toList());
}
User currentUser;
try {
currentUser = userContextService.getCurrentUser();
} catch (UnauthorizedAccessException e) {
currentUser = null;
}

PageRequest pageable = PageRequest.of(page - 1, pageSize);
return questionRepository.searchQuestions(query, tagIds, difficulty, pageable);
if (Objects.equals(sortBy, "default") || Objects.equals(sortBy, null) || Objects.equals(currentUser, null)) {
return questionRepository.searchQuestions(query, tagIds, difficulty, pageable);
} else {
List<Long> authorIds = currentUser.getFollowing().stream()
.map(User::getId) // Map each User to its ID
.collect(Collectors.toList()); // Collect the IDs into a List
return questionRepository.searchQuestionsByRecommended(query, authorIds, tagIds, difficulty, pageable);
}

}

public static QuestionSummaryDto mapToQuestionSummary(Question question) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,5 @@ public Page<User> searchUsers(String query, int page, int pageSize) {
public List<User> getFollowing(User user) {
return user.getFollowing().stream().toList();
}

}
1 change: 1 addition & 0 deletions frontend/src/components/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export const SearchBar = () => {
const params = new URLSearchParams();
params.append("type", searchType);
params.append("q", search);
params.append("sortBy", "recommended");
navigate("/search?" + params.toString());
};

Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/SearchQuestionsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const SearchQuestionsList = () => {
q: params.get("q") ?? "",
pageSize,
...(difficulty && { difficulty }),
sortBy: params.get("sortBy") ?? "recommended"
},
});

Expand Down
6 changes: 6 additions & 0 deletions frontend/src/services/api/programmingForumComponents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1978,6 +1978,12 @@ export type SearchQuestionsQueryParams = {
* @default 20
*/
pageSize?: number;
/**
* Sorting type
*
* @default recommended
*/
sortBy?: string;
};

export type SearchQuestionsError = Fetcher.ErrorWrapper<{
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/services/api/programmingForumSchemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export type UserProfileUpdate = {
};

/**
* @example {"id":1,"username":"john_doe","reputationPoints":100,"profilePicture":"frontend\src\assets\placeholder_profile.png","name":"John Doe"}
* @example {"id":1,"username":"john_doe","reputationPoints":100,"profilePicture":"https://placehold.co/640x640","name":"John Doe"}
*/
export type UserSummary = {
id: number;
Expand Down
6 changes: 6 additions & 0 deletions swagger/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -938,6 +938,12 @@ paths:
schema:
type: integer
default: 20
- name: sortBy
in: query
description: Sorting type
schema:
type: string
default: "recommended"
responses:
"200":
description: Successful response
Expand Down

0 comments on commit 79eb06b

Please sign in to comment.