Skip to content

Commit

Permalink
Changed search to apply on answers and on private chats
Browse files Browse the repository at this point in the history
  • Loading branch information
cremertim committed Oct 28, 2024
1 parent e13b4a8 commit 47c6d5d
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import static de.tum.cit.aet.artemis.communication.repository.MessageSpecs.getConversationsSpecification;
import static de.tum.cit.aet.artemis.communication.repository.MessageSpecs.getCourseWideChannelsSpecification;
import static de.tum.cit.aet.artemis.communication.repository.MessageSpecs.getOwnSpecification;
import static de.tum.cit.aet.artemis.communication.repository.MessageSpecs.getSearchTextSpecification;
import static de.tum.cit.aet.artemis.communication.repository.MessageSpecs.getSortSpecification;
import static de.tum.cit.aet.artemis.communication.repository.MessageSpecs.getUnresolvedSpecification;
import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;
Expand Down Expand Up @@ -53,7 +52,6 @@ public interface ConversationMessageRepository extends ArtemisJpaRepository<Post
private Specification<Post> configureSearchSpecification(Specification<Post> specification, PostContextFilterDTO postContextFilter, long userId) {
return specification
// @formatter:off
.and(getSearchTextSpecification(postContextFilter.searchText()))
.and(getOwnSpecification(Boolean.TRUE.equals(postContextFilter.filterToOwn()), userId))
.and(getAnsweredOrReactedSpecification(Boolean.TRUE.equals(postContextFilter.filterToAnsweredOrReacted()), userId))
.and(getUnresolvedSpecification(Boolean.TRUE.equals(postContextFilter.filterToUnresolved())))
Expand All @@ -72,8 +70,9 @@ private Specification<Post> configureSearchSpecification(Specification<Post> spe
default Page<Post> findMessages(PostContextFilterDTO postContextFilter, Pageable pageable, long userId) {
var specification = Specification.where(getConversationSpecification(postContextFilter.conversationId()));
specification = configureSearchSpecification(specification, postContextFilter, userId);
String searchText = postContextFilter.searchText() != null ? postContextFilter.searchText() : "";
// Fetch all necessary attributes to avoid lazy loading (even though relations are defined as EAGER in the domain class, specification queries do not respect this)
return findPostsWithSpecification(pageable, specification);
return findPostsWithSpecification(pageable, specification, searchText);
}

/**
Expand All @@ -88,17 +87,18 @@ default Page<Post> findCourseWideMessages(PostContextFilterDTO postContextFilter
var specification = Specification.where(getCourseWideChannelsSpecification(postContextFilter.courseId()))
.and(getConversationsSpecification(postContextFilter.courseWideChannelIds()));
specification = configureSearchSpecification(specification, postContextFilter, userId);
return findPostsWithSpecification(pageable, specification);
String searchText = postContextFilter.searchText() != null ? postContextFilter.searchText() : "";
return findPostsWithSpecification(pageable, specification, searchText);
}

private PageImpl<Post> findPostsWithSpecification(Pageable pageable, Specification<Post> specification) {
private PageImpl<Post> findPostsWithSpecification(Pageable pageable, Specification<Post> specification, String searchText) {
// Only fetch the postIds without any left joins to avoid that Hibernate loads all objects and creates the page in Java
long start = System.nanoTime();
Page<Long> postIds = findPostIdsWithSpecification(specification, pageable);
log.debug("findPostIdsWithSpecification took {}", TimeLogUtil.formatDurationFrom(start));
// Fetch all necessary attributes to avoid lazy loading (even though relations are defined as EAGER in the domain class, specification queries do not respect this)
long start2 = System.nanoTime();
List<Post> posts = findByPostIdsWithEagerRelationships(postIds.getContent());
List<Post> posts = findByPostIdsWithEagerRelationships(postIds.getContent(), searchText);
// Make sure to sort the posts in the same order as the postIds
Map<Long, Post> postMap = posts.stream().collect(Collectors.toMap(Post::getId, post -> post));
posts = postIds.stream().map(postMap::get).toList();
Expand All @@ -118,9 +118,9 @@ private PageImpl<Post> findPostsWithSpecification(Pageable pageable, Specificati
LEFT JOIN FETCH a.reactions
LEFT JOIN FETCH a.post
LEFT JOIN FETCH a.author
WHERE p.id IN :postIds
WHERE p.id IN :postIds and (p.content like %:searchText% OR a.content like %:searchText%)
""")
List<Post> findByPostIdsWithEagerRelationships(@Param("postIds") List<Long> postIds);
List<Post> findByPostIdsWithEagerRelationships(@Param("postIds") List<Long> postIds, @Param("searchText") String searchText);

default Post findMessagePostByIdElseThrow(Long postId) throws EntityNotFoundException {
return getValueElseThrow(findById(postId).filter(post -> post.getConversation() != null), postId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import de.tum.cit.aet.artemis.communication.domain.PostSortCriterion;
import de.tum.cit.aet.artemis.communication.domain.Post_;
import de.tum.cit.aet.artemis.communication.domain.Reaction_;
import de.tum.cit.aet.artemis.communication.domain.conversation.Channel;
import de.tum.cit.aet.artemis.communication.domain.conversation.Channel_;
import de.tum.cit.aet.artemis.communication.domain.conversation.Conversation_;
import de.tum.cit.aet.artemis.core.domain.Course_;
Expand Down Expand Up @@ -93,11 +92,11 @@ public static Specification<Post> getCourseWideChannelsSpecification(Long course
return (root, query, criteriaBuilder) -> {
final var conversationJoin = root.join(Post_.conversation, JoinType.LEFT);
final var isInCoursePredicate = criteriaBuilder.equal(conversationJoin.get(Channel_.COURSE).get(Course_.ID), courseId);
final var isCourseWidePredicate = criteriaBuilder.isTrue(conversationJoin.get(Channel_.IS_COURSE_WIDE));
// final var isCourseWidePredicate = criteriaBuilder.isTrue(conversationJoin.get(Channel_.IS_COURSE_WIDE));
// make sure we only fetch channels (which are sub types of conversations)
// this avoids the creation of sub queries
final var isChannelPredicate = criteriaBuilder.equal(conversationJoin.type(), criteriaBuilder.literal(Channel.class));
return criteriaBuilder.and(isInCoursePredicate, isCourseWidePredicate, isChannelPredicate);
// final var isChannelPredicate = criteriaBuilder.equal(conversationJoin.type(), criteriaBuilder.literal(Channel.class));
return criteriaBuilder.and(isInCoursePredicate);
};
}

Expand Down

0 comments on commit 47c6d5d

Please sign in to comment.