@Test public void simpleFacetsAreParsed() throws Exception { final TermFacetExpression<ProductProjection> facetExpr = TermFacetExpression.of("variants.attributes." + ATTR_NAME_COLOR); final ProductProjectionSearch search = ProductProjectionSearch.ofStaged().plusFacets(facetExpr); testResult(search, result -> { final TermFacetResult termFacetResult = result.getFacetResult(facetExpr); assertThat(termFacetResult.getMissing()).isGreaterThanOrEqualTo(3); assertThat(termFacetResult.getTotal()).isEqualTo(3); assertThat(termFacetResult.getOther()).isEqualTo(0); assertThat(termFacetResult.getTerms()).isEqualTo(asList(TermStats.of("blue", 2L), TermStats.of("red", 1L))); }); }
@Test public void rangeFacetsAreParsed() throws Exception { final RangeFacetExpression<ProductProjection> facetExpr = PRODUCT_MODEL.allVariants().attribute().ofNumber(ATTR_NAME_SIZE).onlyGreaterThanOrEqualTo(ZERO); final ProductProjectionSearch search = ProductProjectionSearch.ofStaged().plusFacets(facetExpr); testResult(search, result -> { final RangeStats rangeStats = result.getFacetResult(facetExpr).getRanges().get(0); assertThat(rangeStats.getLowerEndpoint()).isEqualTo("0.0"); assertThat(rangeStats.getUpperEndpoint()).isNull(); assertThat(rangeStats.getCount()).isEqualTo(6L); assertThat(rangeStats.getMin()).isEqualTo("36.0"); assertThat(rangeStats.getMax()).isEqualTo("46.0"); assertThat(rangeStats.getSum()).isEqualTo("246.0"); assertThat(rangeStats.getMean()).isEqualTo(41.0); }); }
@Test public void rangeFacetsSupportsAlias() throws Exception { final String alias = "my-facet"; final RangeFacetExpression<ProductProjection> facetExpr = PRODUCT_MODEL.allVariants().attribute().ofNumber(ATTR_NAME_SIZE).withAlias(alias).onlyGreaterThanOrEqualTo(ZERO); final ProductProjectionSearch search = ProductProjectionSearch.ofStaged().plusFacets(facetExpr); testResult(search, result -> { assertThat(facetExpr.resultPath()).isEqualTo(alias); final RangeStats rangeStats = result.getFacetResult(facetExpr).getRanges().get(0); assertThat(rangeStats.getLowerEndpoint()).isEqualTo("0.0"); assertThat(rangeStats.getUpperEndpoint()).isNull(); assertThat(rangeStats.getCount()).isEqualTo(6L); assertThat(rangeStats.getMin()).isEqualTo("36.0"); assertThat(rangeStats.getMax()).isEqualTo("46.0"); assertThat(rangeStats.getSum()).isEqualTo("246.0"); assertThat(rangeStats.getMean()).isEqualTo(41.0); }); }
@Test public void filterQueryFiltersBeforeFacetsAreCalculated() throws Exception { final ProductProjectionSearch search = ProductProjectionSearch.ofStaged() .plusFacets(SIZE_FACETED_SEARCH.facetExpression()) .plusFacets(COLOR_FACETED_SEARCH.facetExpression()) .plusQueryFilters(COLOR_FACETED_SEARCH.filterExpressions()); testResult(search, ids -> assertThat(ids).containsOnly(product2.getId()), colors -> assertThat(colors).containsOnly(TermStats.of("red", 1L)), sizes -> assertThat(sizes).containsOnly(TermStats.of("36.0", 1L))); }
@Test public void filteredFacetsSupportsAlias() throws Exception { final String alias = "my-facet"; final FilteredFacetExpression<ProductProjection> facetExpr = PRODUCT_MODEL.allVariants().attribute().ofString(ATTR_NAME_COLOR).withAlias(alias).onlyTerm("blue"); final ProductProjectionSearch search = ProductProjectionSearch.ofStaged().plusFacets(facetExpr); testResult(search, result -> { assertThat(facetExpr.resultPath()).isEqualTo(alias); assertThat(result.getFacetResult(facetExpr).getCount()).isEqualTo(2); }); }
@Test public void termFacetsAreParsed() throws Exception { final TermFacetExpression<ProductProjection> facetExpr = PRODUCT_MODEL.allVariants().attribute().ofString(ATTR_NAME_COLOR).allTerms(); final ProductProjectionSearch search = ProductProjectionSearch.ofStaged().plusFacets(facetExpr); testResult(search, result -> { final TermFacetResult termFacetResult = result.getFacetResult(facetExpr); assertThat(termFacetResult.getMissing()).isGreaterThanOrEqualTo(3); assertThat(termFacetResult.getTotal()).isEqualTo(3); assertThat(termFacetResult.getOther()).isEqualTo(0); assertThat(termFacetResult.getTerms()).isEqualTo(asList(TermStats.of("blue", 2L), TermStats.of("red", 1L))); }); }
@Test public void resultsAndFacetsAreFiltered() throws Exception { final ProductProjectionSearch search = ProductProjectionSearch.ofStaged() .plusFacets(SIZE_FACETED_SEARCH.facetExpression()) .plusFacets(COLOR_FACETED_SEARCH.facetExpression()) .plusResultFilters(COLOR_FACETED_SEARCH.filterExpressions()) .plusFacetFilters(COLOR_FACETED_SEARCH.filterExpressions()); testResult(search, ids -> assertThat(ids).containsOnly(product2.getId()), colors -> assertThat(colors).containsOnly(TermStats.of("blue", 2L), TermStats.of("red", 1L)), sizes -> assertThat(sizes).containsOnly(TermStats.of("36.0", 1L))); }
@Test public void filteredFacetsAreParsed() throws Exception { final FilteredFacetExpression<ProductProjection> facetExpr = PRODUCT_MODEL.allVariants().attribute().ofString(ATTR_NAME_COLOR).onlyTerm("blue"); final ProductProjectionSearch search = ProductProjectionSearch.ofStaged().plusFacets(facetExpr); testResult(search, result -> { final FilteredFacetResult filteredFacetResult = result.getFacetResult(facetExpr); assertThat(filteredFacetResult.getCount()).isEqualTo(2); }); }
@Test public void onlyFacetsAreFiltered() throws Exception { final ProductProjectionSearch search = ProductProjectionSearch.ofStaged() .plusFacets(SIZE_FACETED_SEARCH.facetExpression()) .plusFacets(COLOR_FACETED_SEARCH.facetExpression()) .plusFacetFilters(COLOR_FACETED_SEARCH.filterExpressions()); testResult(search, ids -> assertThat(ids).containsOnly(product1.getId(), product2.getId(), product3.getId()), colors -> assertThat(colors).containsOnly(TermStats.of("blue", 2L), TermStats.of("red", 1L)), sizes -> assertThat(sizes).containsOnly(TermStats.of("36.0", 1L))); }
@Test public void termFacetsSupportsAlias() throws Exception { final String allFacetAlias = "my-facet"; final String blueFacetAlias = "my-blue-facet"; final TermFacetExpression<ProductProjection> allFacetExpr = PRODUCT_MODEL.allVariants().attribute().ofString(ATTR_NAME_COLOR).withAlias(allFacetAlias).allTerms(); final FilteredFacetExpression<ProductProjection> blueFacetExpr = PRODUCT_MODEL.allVariants().attribute().ofString(ATTR_NAME_COLOR).withAlias(blueFacetAlias).onlyTerm("blue"); final ProductProjectionSearch search = ProductProjectionSearch.ofStaged() .plusFacets(allFacetExpr) .plusFacets(blueFacetExpr); testResult(search, result -> { final TermFacetResult allFacetResult = result.getFacetResult(allFacetExpr); final FilteredFacetResult blueFacetResult = result.getFilteredFacetResult(blueFacetAlias); assertThat(allFacetExpr.resultPath()).isEqualTo(allFacetAlias); assertThat(blueFacetExpr.resultPath()).isEqualTo(blueFacetAlias); assertThat(allFacetResult.getTerms()).isEqualTo(asList(TermStats.of("blue", 2L), TermStats.of("red", 1L))); assertThat(blueFacetResult.getCount()).isEqualTo(2); }); }
@Test public void onlyResultsAreFiltered() throws Exception { final ProductProjectionSearch search = ProductProjectionSearch.ofStaged() .plusFacets(SIZE_FACETED_SEARCH.facetExpression()) .plusFacets(COLOR_FACETED_SEARCH.facetExpression()) .plusResultFilters(COLOR_FACETED_SEARCH.filterExpressions()); testResult(search, ids -> assertThat(ids).containsOnly(product2.getId()), colors -> assertThat(colors).containsOnly(TermStats.of("blue", 2L), TermStats.of("red", 1L)), sizes -> assertThat(sizes).containsOnly(TermStats.of("36.0", 1L), TermStats.of("38.0", 1L), TermStats.of("40.0", 1L), TermStats.of("42.0", 1L), TermStats.of("44.0", 1L), TermStats.of("46.0", 1L))); }
@Test public void responseContainsRangeFacetsForAttributes() throws Exception { final RangeFacetExpression<ProductProjection> facetExpr = PRODUCT_MODEL.allVariants().price().centAmount().onlyGreaterThanOrEqualTo(0L); final ProductProjectionSearch search = ProductProjectionSearch.ofStaged().plusFacets(facetExpr); testResult(search, result -> assertThat(result.getFacetResult(facetExpr).getRanges().get(0).getCount()).isGreaterThan(0)); }
@Test public void searchForAvailableQuantityRanges() { withProductOfStock(client(), 10, productWith10Items -> { withProductOfStock(client(), 5, productWith5Items -> { final RangeFacetExpression<ProductProjection> productProjectionRangeFacetExpression = ProductProjectionSearchModel.of() .facet().allVariants().availability().availableQuantity().onlyGreaterThanOrEqualTo(new BigDecimal(1)); final ProductProjectionSearch request = ProductProjectionSearch.ofStaged() .plusQueryFilters(m -> m.id().isIn(asList(productWith10Items.getId(), productWith5Items.getId()))) .plusQueryFilters(m -> m.allVariants().availability().availableQuantity().isGreaterThanOrEqualTo(new BigDecimal(6))) .plusFacets(productProjectionRangeFacetExpression); assertEventually(() -> { final PagedSearchResult<ProductProjection> res = client().executeBlocking(request); assertThat(res.getResults()).hasSize(1); assertThat(res.getResults().get(0).getId()) .as("finds only the product with the sufficient amount stocked") .isEqualTo(productWith10Items.getId()); final RangeFacetResult facetResult = res.getFacetResult(productProjectionRangeFacetExpression); assertThat(facetResult.getRanges().get(0).getMax()) .isEqualTo("10.0"); }); }); }); }
@Test public void responseContainsTermFacetsForAttributes() throws Exception { final TermFacetExpression<ProductProjection> facetExpr = PRODUCT_MODEL.allVariants().attribute().ofString(ATTR_NAME_COLOR).allTerms(); final ProductProjectionSearch search = ProductProjectionSearch.ofStaged().plusFacets(facetExpr); testResult(search, result -> assertThat(result.getFacetResult(facetExpr).getTerms()).containsOnly(TermStats.of("blue", 2L), TermStats.of("red", 1L))); }
@Test public void facetedSearchVerboseExample() throws Exception { final ProductProjectionSearch search = ProductProjectionSearch.ofStaged() .plusFacets(facet -> facet.allVariants().attribute().ofString(ATTR_NAME_COLOR).allTerms()) .plusFacets(facet -> facet.allVariants().attribute().ofNumber(ATTR_NAME_SIZE).allTerms()) .plusResultFilters(filter -> filter.allVariants().attribute().ofString(ATTR_NAME_COLOR).is("red")) .plusFacetFilters(filter -> filter.allVariants().attribute().ofString(ATTR_NAME_COLOR).is("red")); testResult(search, ids -> assertThat(ids).containsOnly(product2.getId()), colors -> assertThat(colors).containsOnly(TermStats.of("blue", 2L), TermStats.of("red", 1L)), sizes -> assertThat(sizes).containsOnly(TermStats.of("36.0", 1L))); }
@Test public void facet() { final List<String> categoryIds1 = getCategoryIds("A", "B-1", "C-2-2"); final List<String> categoryIds2 = getCategoryIds("A", "B-2-3"); final List<String> categoryIds3 = getCategoryIds("B", "C"); withProductInCategories(client(), categoryIds1, (Product product1) -> { withProductInCategories(client(), categoryIds2, (Product product2) -> { withProductInCategories(client(), categoryIds3, (Product product3) -> { assertEventually(() -> { final ProductProjectionSearch request = ProductProjectionSearch.ofStaged() .plusFacets(m -> m.categories().id().withAlias("productsInA").onlyTermSubtree(getCategoryIds("A"))) .plusFacets(m -> m.categories().id().withAlias("productsInB").onlyTermSubtree(getCategoryIds("B"))) .plusFacets(m -> m.categories().id().withAlias("productsInAorB").onlyTermSubtree(getCategoryIds("A", "B"))) .plusFacets(m -> m.categories().id().withAlias("productsInC2").onlyTermSubtree(getCategoryIds("C-2"))) .plusQueryFilters(m -> m.id().isIn(asList(product1.getId(), product2.getId(), product3.getId()))); final PagedSearchResult<ProductProjection> pagedSearchResult = client().executeBlocking(request); assertThat(pagedSearchResult.getFilteredFacetResult("productsInA").getCount()).isEqualTo(2); assertThat(pagedSearchResult.getFilteredFacetResult("productsInB").getCount()).isEqualTo(3); assertThat(pagedSearchResult.getFilteredFacetResult("productsInAorB").getCount()).isEqualTo(3); assertThat(pagedSearchResult.getFilteredFacetResult("productsInC2").getCount()).isEqualTo(1); }); }); }); }); }
@Test public void searchByCount() { final ProductProjectionSearch projectionSearch = ProductProjectionSearch.ofStaged()//in prod it would be current .withResultFilters(m -> m.reviewRatingStatistics().count().isGreaterThanOrEqualTo(new BigDecimal(2))) .plusResultFilters(m -> m.reviewRatingStatistics().highestRating().isGreaterThanOrEqualTo(new BigDecimal(2))) .plusResultFilters(m -> m.reviewRatingStatistics().lowestRating().isGreaterThanOrEqualTo(new BigDecimal(0))) .plusFacets(m -> m.reviewRatingStatistics().count().allRanges()) .plusFacets(m -> m.reviewRatingStatistics().highestRating().allRanges()) .plusFacets(m -> m.reviewRatingStatistics().lowestRating().allRanges()) ; assertEventually(Duration.ofSeconds(60), Duration.ofMillis(100), () -> { softAssert(soft -> { final PagedSearchResult<ProductProjection> res = client().executeBlocking(projectionSearch); soft.assertThat(res.getCount()).isGreaterThanOrEqualTo(3); final RangeFacetResult countFacets = (RangeFacetResult) res.getFacetResult("reviewRatingStatistics.count"); soft.assertThat(countFacets.getRanges().get(1).getSum()).as("count facets").isEqualTo("60.0"); final RangeFacetResult lowestRatingFacets = (RangeFacetResult) res.getFacetResult("reviewRatingStatistics.lowestRating"); soft.assertThat(lowestRatingFacets.getRanges().get(1).getSum()).as("lowestRating facets").isEqualTo("0.0"); final RangeFacetResult highestRatingFacets = (RangeFacetResult) res.getFacetResult("reviewRatingStatistics.highestRating"); soft.assertThat(highestRatingFacets.getRanges().get(1).getSum()).as("highestRating facets").isEqualTo("14.0"); }); }); }
@Test public void searchForAvailableQuantityRangesInChannels() { withChannelOfRole(client(), ChannelRole.INVENTORY_SUPPLY, channel -> { withProductOfStockAndChannel(client(), 10, channel, productWith10Items -> { withProductOfStockAndChannel(client(), 5, channel, productWith5Items -> { final RangeFacetExpression<ProductProjection> facet = ProductProjectionSearchModel.of() .facet().allVariants().availability().channels().channelId(channel.getId()) .availableQuantity().onlyGreaterThanOrEqualTo(new BigDecimal(1)); final ProductProjectionSearch request = ProductProjectionSearch.ofStaged() .plusQueryFilters(m -> m.id().isIn(asList(productWith10Items.getId(), productWith5Items.getId()))) .plusQueryFilters(m -> m.allVariants().availability().channels().channelId(channel.getId()) .availableQuantity().isGreaterThanOrEqualTo(new BigDecimal(6))) .plusFacets(facet); assertEventually(() -> { final PagedSearchResult<ProductProjection> res = client().executeBlocking(request); assertThat(res.getResults()).hasSize(1); assertThat(res.getResults().get(0).getId()) .as("finds only the product with the sufficient amount stocked") .isEqualTo(productWith10Items.getId()); final RangeFacetResult facetResult = res.getFacetResult(facet); assertThat(facetResult.getRanges().get(0).getMax()) .isEqualTo("10.0"); }); }); }); }); }