Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backend] Sort Questions by Followed Users #691

Merged
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,33 @@ 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(currentUser, null)) {
ozdentarikcan marked this conversation as resolved.
Show resolved Hide resolved
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");
ozdentarikcan marked this conversation as resolved.
Show resolved Hide resolved
navigate("/search?" + params.toString());
};

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
Loading