summaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <code@mail.matthias.benkard.de>2020-09-16 17:57:24 +0200
committerMatthias Andreas Benkard <code@mail.matthias.benkard.de>2020-09-17 11:03:14 +0200
commit8563a3c03538600ae148b75debd31af16047e2d5 (patch)
tree7ac292f7213bb6118552b94442533e9e685b11e1 /src/main/java
parentb1192ac9ed515927642215dd3a1717fc13c9679c (diff)
KB73 Add full text search to post lists.
Change-Id: Ib8333b39cef1d7035ab7fac0ff8a03b400adcb40
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/eu/mulk/mulkcms2/benki/posts/Post.java36
-rw-r--r--src/main/java/eu/mulk/mulkcms2/benki/posts/PostResource.java10
-rw-r--r--src/main/java/eu/mulk/mulkcms2/benki/posts/PostText.java6
3 files changed, 41 insertions, 11 deletions
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<Text extends PostText<?>> extends PanacheEntityBase {
@CheckForNull User owner,
@CheckForNull Integer cursor,
CriteriaBuilder cb,
- boolean forward) {
+ boolean forward,
+ @CheckForNull String searchQuery) {
CriteriaQuery<T> query = cb.createQuery(entityClass);
var conditions = new ArrayList<Predicate>();
@@ -177,6 +179,23 @@ public abstract class Post<Text extends PostText<?>> 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<Text extends PostText<?>> extends PanacheEntityBase {
public static PostPage<Post<? extends PostText>> 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<Post<? extends PostText>> findViewable(
@@ -257,7 +276,8 @@ public abstract class Post<Text extends PostText<?>> extends PanacheEntityBase {
@CheckForNull User viewer,
@CheckForNull User owner,
@CheckForNull Integer cursor,
- @CheckForNull Integer count) {
+ @CheckForNull Integer count,
+ @CheckForNull String searchQuery) {
Class<? extends Post> entityClass;
switch (postFilter) {
case BOOKMARKS_ONLY:
@@ -269,7 +289,7 @@ public abstract class Post<Text extends PostText<?>> 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 <T extends Post<? extends PostText>> PostPage<T> findViewable(
@@ -278,7 +298,8 @@ public abstract class Post<Text extends PostText<?>> 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<Text extends PostText<?>> 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<Text extends PostText<?>> 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<OwningPost extends Post<?>> 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