From 8563a3c03538600ae148b75debd31af16047e2d5 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Wed, 16 Sep 2020 17:57:24 +0200 Subject: KB73 Add full text search to post lists. Change-Id: Ib8333b39cef1d7035ab7fac0ff8a03b400adcb40 --- .../java/eu/mulk/mulkcms2/benki/posts/Post.java | 36 +++++++++++++++++----- .../eu/mulk/mulkcms2/benki/posts/PostResource.java | 10 +++--- .../eu/mulk/mulkcms2/benki/posts/PostText.java | 6 ++++ 3 files changed, 41 insertions(+), 11 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/eu/mulk/mulkcms2/benki/posts/Post.java b/src/main/java/eu/mulk/mulkcms2/benki/posts/Post.java index 8f2166c..fd023d7 100644 --- a/src/main/java/eu/mulk/mulkcms2/benki/posts/Post.java +++ b/src/main/java/eu/mulk/mulkcms2/benki/posts/Post.java @@ -19,6 +19,7 @@ import java.util.Objects; import java.util.Set; import java.util.TimeZone; import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import javax.json.bind.annotation.JsonbTransient; @@ -132,7 +133,8 @@ public abstract class Post> extends PanacheEntityBase { @CheckForNull User owner, @CheckForNull Integer cursor, CriteriaBuilder cb, - boolean forward) { + boolean forward, + @CheckForNull String searchQuery) { CriteriaQuery query = cb.createQuery(entityClass); var conditions = new ArrayList(); @@ -177,6 +179,23 @@ public abstract class Post> extends PanacheEntityBase { } } + if (searchQuery != null && !searchQuery.isBlank()) { + var postTexts = post.join(Post_.texts); + var localizedSearches = + Stream.of("de", "en") + .map( + language -> + cb.isTrue( + cb.function( + "post_matches_websearch", + Boolean.class, + postTexts.get(PostText_.searchTerms), + cb.literal(language), + cb.literal(searchQuery)))) + .toArray(n -> new Predicate[n]); + conditions.add(cb.or(localizedSearches)); + } + query.where(conditions.toArray(new Predicate[0])); return query; @@ -248,7 +267,7 @@ public abstract class Post> extends PanacheEntityBase { public static PostPage> findViewable( PostFilter postFilter, Session session, @CheckForNull User viewer, @CheckForNull User owner) { - return findViewable(postFilter, session, viewer, owner, null, null); + return findViewable(postFilter, session, viewer, owner, null, null, null); } public static PostPage> findViewable( @@ -257,7 +276,8 @@ public abstract class Post> extends PanacheEntityBase { @CheckForNull User viewer, @CheckForNull User owner, @CheckForNull Integer cursor, - @CheckForNull Integer count) { + @CheckForNull Integer count, + @CheckForNull String searchQuery) { Class entityClass; switch (postFilter) { case BOOKMARKS_ONLY: @@ -269,7 +289,7 @@ public abstract class Post> extends PanacheEntityBase { default: entityClass = Post.class; } - return findViewable(entityClass, session, viewer, owner, cursor, count); + return findViewable(entityClass, session, viewer, owner, cursor, count, searchQuery); } protected static > PostPage findViewable( @@ -278,7 +298,8 @@ public abstract class Post> extends PanacheEntityBase { @CheckForNull User viewer, @CheckForNull User owner, @CheckForNull Integer cursor, - @CheckForNull Integer count) { + @CheckForNull Integer count, + @CheckForNull String searchQuery) { if (cursor != null) { Objects.requireNonNull(count); @@ -286,7 +307,7 @@ public abstract class Post> extends PanacheEntityBase { var cb = session.getCriteriaBuilder(); - var forwardCriteria = queryViewable(entityClass, viewer, owner, cursor, cb, true); + var forwardCriteria = queryViewable(entityClass, viewer, owner, cursor, cb, true, searchQuery); var forwardQuery = session.createQuery(forwardCriteria); if (count != null) { @@ -300,7 +321,8 @@ public abstract class Post> extends PanacheEntityBase { if (cursor != null) { // Look backwards as well so we can find the prevCursor. - var backwardCriteria = queryViewable(entityClass, viewer, owner, cursor, cb, false); + var backwardCriteria = + queryViewable(entityClass, viewer, owner, cursor, cb, false, searchQuery); var backwardQuery = session.createQuery(backwardCriteria); backwardQuery.setMaxResults(count); var backwardResults = backwardQuery.getResultList(); diff --git a/src/main/java/eu/mulk/mulkcms2/benki/posts/PostResource.java b/src/main/java/eu/mulk/mulkcms2/benki/posts/PostResource.java index 47e1594..59cacee 100644 --- a/src/main/java/eu/mulk/mulkcms2/benki/posts/PostResource.java +++ b/src/main/java/eu/mulk/mulkcms2/benki/posts/PostResource.java @@ -116,13 +116,14 @@ public abstract class PostResource { @Transactional public TemplateInstance getIndex( @QueryParam("i") @CheckForNull Integer cursor, - @QueryParam("n") @CheckForNull Integer maxResults) { + @QueryParam("n") @CheckForNull Integer maxResults, + @QueryParam("search-query") @CheckForNull String searchQuery) { maxResults = maxResults == null ? defaultMaxResults : maxResults; @CheckForNull var reader = getCurrentUser(); var session = entityManager.unwrap(Session.class); - var q = Post.findViewable(postFilter, session, reader, null, cursor, maxResults); + var q = Post.findViewable(postFilter, session, reader, null, cursor, maxResults, searchQuery); q.cacheDescriptions(); @@ -142,7 +143,8 @@ public abstract class PostResource { .data("hasNextPage", q.nextCursor != null) .data("previousCursor", q.prevCursor) .data("nextCursor", q.nextCursor) - .data("pageSize", maxResults); + .data("pageSize", maxResults) + .data("searchQuery", searchQuery); } @GET @@ -159,7 +161,7 @@ public abstract class PostResource { @CheckForNull var reader = getCurrentUser(); var owner = User.findByNickname(ownerName); var session = entityManager.unwrap(Session.class); - var q = Post.findViewable(postFilter, session, reader, owner, cursor, maxResults); + var q = Post.findViewable(postFilter, session, reader, owner, cursor, maxResults, null); q.cacheDescriptions(); diff --git a/src/main/java/eu/mulk/mulkcms2/benki/posts/PostText.java b/src/main/java/eu/mulk/mulkcms2/benki/posts/PostText.java index 8b1697c..25955bd 100644 --- a/src/main/java/eu/mulk/mulkcms2/benki/posts/PostText.java +++ b/src/main/java/eu/mulk/mulkcms2/benki/posts/PostText.java @@ -13,6 +13,8 @@ import javax.persistence.InheritanceType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; +import org.hibernate.annotations.Generated; +import org.hibernate.annotations.GenerationTime; @Entity @Table(name = "post_texts", schema = "benki") @@ -38,6 +40,10 @@ public abstract class PostText> extends PanacheEntity @CheckForNull public String cachedDescriptionHtml; + @Column(name = "search_terms") + @Generated(GenerationTime.ALWAYS) + public String searchTerms; + @ManyToOne(fetch = FetchType.LAZY, targetEntity = Post.class) @JoinColumn(name = "post", referencedColumnName = "id", nullable = false) @JsonbTransient -- cgit v1.2.3