diff --git a/src/main/java/io/quarkus/search/app/SearchService.java b/src/main/java/io/quarkus/search/app/SearchService.java index 76949789..bdd1a441 100644 --- a/src/main/java/io/quarkus/search/app/SearchService.java +++ b/src/main/java/io/quarkus/search/app/SearchService.java @@ -1,5 +1,7 @@ package io.quarkus.search.app; +import java.util.List; + import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.transaction.Transactional; @@ -33,6 +35,7 @@ public class SearchService { @Operation(summary = "Search for any resource") @Transactional public SearchResult search(@RestQuery @DefaultValue(QuarkusVersions.LATEST) String version, + @RestQuery List categories, @RestQuery String q, @RestQuery @DefaultValue("0") int page) { var result = session.search(Guide.class) @@ -43,6 +46,10 @@ public SearchResult search(@RestQuery @DefaultValue(QuarkusVersions.L root.add(f.match().field("version").matching(version)); + if (categories != null && !categories.isEmpty()) { + root.add(f.terms().field("categories").matchingAny(categories)); + } + if (q != null && !q.isBlank()) { root.add(f.bool().must(f.simpleQueryString() .field("title").boost(10.0f) diff --git a/src/main/java/io/quarkus/search/app/entity/Guide.java b/src/main/java/io/quarkus/search/app/entity/Guide.java index e009f943..628b3f4c 100644 --- a/src/main/java/io/quarkus/search/app/entity/Guide.java +++ b/src/main/java/io/quarkus/search/app/entity/Guide.java @@ -49,6 +49,9 @@ public class Guide { // Using PathWrapper because of https://hibernate.atlassian.net/browse/HSEARCH-4988 public PathWrapper fullContentPath; + @KeywordField(name = "categories") + public Set categories; + @FullTextField(name = "topics") @KeywordField(name = "topics_faceting", searchable = Searchable.YES, projectable = Projectable.YES, aggregable = Aggregable.YES) public Set topics; diff --git a/src/main/java/io/quarkus/search/app/fetching/QuarkusIO.java b/src/main/java/io/quarkus/search/app/fetching/QuarkusIO.java index 8402c3f2..a5a17fd1 100644 --- a/src/main/java/io/quarkus/search/app/fetching/QuarkusIO.java +++ b/src/main/java/io/quarkus/search/app/fetching/QuarkusIO.java @@ -62,6 +62,7 @@ private Guide parseGuide(GuidesDirectory guidesDirectory, Path path) { Asciidoc.parse(path, title -> guide.title = title, Map.of("summary", summary -> guide.summary = summary, "keywords", keywords -> guide.keywords = keywords, + "categories", categories -> guide.categories = toSet(categories), "topics", topics -> guide.topics = toSet(topics), "extensions", extensions -> guide.extensions = toSet(extensions))); return guide; diff --git a/src/test/java/io/quarkus/search/app/SearchServiceTest.java b/src/test/java/io/quarkus/search/app/SearchServiceTest.java index 7a093bef..2e711806 100644 --- a/src/test/java/io/quarkus/search/app/SearchServiceTest.java +++ b/src/test/java/io/quarkus/search/app/SearchServiceTest.java @@ -217,4 +217,17 @@ void version() { .allSatisfy(hit -> assertThat(hit).extracting(SearchHit::id, InstanceOfAssertFactories.STRING) .startsWith("/versions/main/guides/")); } + + @Test + void categories() { + var result = given() + .queryParam("q", "orm") + .queryParam("categories", "alt-languages") + .when().get() + .then() + .statusCode(200) + .extract().body().as(SEARCH_RESULT_SEARCH_HITS); + assertThat(result.hits()).extracting(SearchHit::id).containsExactlyInAnyOrder( + GuideIds.HIBERNATE_ORM_PANACHE_KOTLIN); + } }