private void checkSorting(final Function<ProductProjectionSortSearchModel, SortExpression<ProductProjection>> sortExpressionFunction, final Consumer<ProductProjection> asserter) { final ProductProjectionSearch productProjectionSearch = ProductProjectionSearch.ofStaged() .withQueryFilters(m -> m.reviewRatingStatistics().count().isGreaterThanOrEqualTo(BigDecimal.ZERO)) .withSort(sortExpressionFunction); assertEventually(Duration.ofSeconds(15), Duration.ofMillis(200), () -> { final List<ProductProjection> results = client().executeBlocking(productProjectionSearch).getResults(); assertThat(results.size()).isGreaterThanOrEqualTo(3); final ProductProjection first = results.get(0); asserter.accept(first); }); } }
private static void testProductIds(final SortExpression<ProductProjection> sortExpr, final Consumer<List<String>> test) { final ProductProjectionSearch search = ProductProjectionSearch.ofStaged().withSort(sortExpr); final List<ProductProjection> results = executeSearch(search).getResults(); assertEventually(() -> { test.accept(toIds(results)); }); } }
@Test public void sortWithSimpleExpression() { final SortExpression<ProductProjection> sort = SortExpression.of("variants.attributes." + ATTR_NAME_SIZE + " asc.max"); final ProductProjectionSearch search = ProductProjectionSearch.ofStaged().withSort(sort); testResultIds(search, resultIds -> assertThat(resultIds).containsExactly(product3.getId(), product2.getId(), product1.getId())); }
@Test public void searchForReviewsWithAverageRatingGreaterThan2() { final List<FacetRange<BigDecimal>> facetRanges = IntStream.range(LOWEST_RATING, HIGHEST_RATING) .mapToObj(i -> FacetRange.of(new BigDecimal(i), new BigDecimal(i + 1))) .collect(toList()); assertThat(facetRanges.toString()).isEqualTo("[[0 to 1), [1 to 2), [2 to 3), [3 to 4), [4 to 5)]"); final ProductProjectionSearch searchRequest = ProductProjectionSearch.ofStaged()//in prod it would be current .withResultFilters(m -> m.reviewRatingStatistics().averageRating().isGreaterThanOrEqualTo(new BigDecimal(2))) .withFacets(m -> m.reviewRatingStatistics().averageRating().onlyRange(facetRanges)) .withSort(m -> m.reviewRatingStatistics().averageRating().desc()); assertEventually(Duration.ofSeconds(60), Duration.ofMillis(100), () -> { final PagedSearchResult<ProductProjection> result = client().executeBlocking(searchRequest); assertThat(result.getResults()).hasSize(2); final ProductProjection productProjection = result.getResults().get(0); assertThat(productProjection.getReviewRatingStatistics().getCount()).isEqualTo(REVIEWS_PER_PRODUCT); final RangeFacetResult facetResult = (RangeFacetResult) result.getFacetResult("reviewRatingStatistics.averageRating"); assertThat(facetResult.getRanges().get(2)).isEqualTo(RangeStats.of("2.0", "3.0", 2L, null, "2.2", "2.7", "4.9", 2.45)); }); }
@Test public void id() { final ProductProjectionSearch baseRequest = ProductProjectionSearch.ofStaged() .withQueryFilters(m -> m.id().isIn(getAllIds())); final ProductProjectionSearch asc = baseRequest.withSort(m -> m.id().asc()); final ProductProjectionSearch desc = baseRequest.withSort(m -> m.id().desc()); assertEventually(() -> { final PagedSearchResult<ProductProjection> ascResult = client().executeBlocking(asc); assertThat(ascResult.getTotal()).isEqualTo(getAllIds().size()); final PagedSearchResult<ProductProjection> descResult = client().executeBlocking(desc); assertThat(descResult.getTotal()).isEqualTo(getAllIds().size()); final LinkedList<ProductProjection> reversedDesc = new LinkedList<>(descResult.getResults()); Collections.reverse(reversedDesc); assertThat(ascResult.getResults()).isEqualTo(reversedDesc); }); }
@Test public void sortByAttributeAscending() throws Exception { final ProductProjectionSearch search = ProductProjectionSearch.ofStaged() .withSort(productModel -> productModel.allVariants().attribute().ofNumber(ATTR_NAME_SIZE).asc()); testResultIds(search, resultIds -> assertThat(resultIds).containsExactly(product2.getId(), product1.getId(), product3.getId())); }
@Test public void sortWithAdditionalParameterByAttributeDescending() throws Exception { final ProductProjectionSearch search = ProductProjectionSearch.ofStaged() .withSort(productModel -> productModel.allVariants().attribute().ofNumber(ATTR_NAME_SIZE).descWithMinValue()); testResultIds(search, resultIds -> assertThat(resultIds).containsExactly(product3.getId(), product1.getId(), product2.getId())); }
@Test public void sortByAttributeDescending() throws Exception { final ProductProjectionSearch search = ProductProjectionSearch.ofStaged() .withSort(productModel -> productModel.allVariants().attribute().ofNumber(ATTR_NAME_SIZE).desc()); testResultIds(search, resultIds -> assertThat(resultIds).containsExactly(product1.getId(), product2.getId(), product3.getId())); }
@Test public void score() { final ProductProjectionSearch baseRequest = ProductProjectionSearch.ofStaged() .withQueryFilters(m -> m.id().isIn(getAllIds())); final ProductProjectionSearch asc = baseRequest.withSort(m -> m.score().asc()); assertEventually(() -> { final PagedSearchResult<ProductProjection> ascResult = client().executeBlocking(asc); assertThat(ascResult.getTotal()).isEqualTo(getAllIds().size()); }); }
@Test public void sortWithAdditionalParameterByAttributeAscending() throws Exception { final ProductProjectionSearch search = ProductProjectionSearch.ofStaged() .withSort(productModel -> productModel.allVariants().attribute().ofNumber(ATTR_NAME_SIZE).ascWithMaxValue()); testResultIds(search, resultIds -> assertThat(resultIds).containsExactly(product3.getId(), product2.getId(), product1.getId())); }
@Ignore // HTTP API still not having sort associated to matching variant flag @Test public void findMatchingVariantBySort() throws Exception { final ProductProjectionSearch search = ProductProjectionSearch.ofStaged() .withSort(productModel -> productModel.allVariants().attribute().ofNumber(ATTR_NAME_SIZE).ascWithMaxValue()); testResult(search, result -> assertThat(result.getResults()).are(productWithMatchingVariantsHavingMaxSize())); }
@Test public void resultsArePaginated() throws Exception { final ProductProjectionSearch search = ProductProjectionSearch.ofStaged() .plusQueryFilters(productModel -> productModel.allVariants().attribute().ofString(ATTR_NAME_COLOR).isIn(asList("blue", "red"))) .withSort(sort -> sort.name().locale(ENGLISH).desc()) .withOffset(1L) .withLimit(1L); testResultIds(search, resultIds -> assertThat(resultIds).containsOnly(product2.getId())); }
/** * Gets the products belonging to the given categories, up to {@code numProducts}, most expensive products first. * @param categoryIds the category IDs to get products from * @param numProducts the number of products the returned set should contain * @return the products related to these categories */ private CompletionStage<Set<ProductProjection>> productsFromCategoryIds(final Iterable<String> categoryIds, final int numProducts) { final ProductProjectionSearch request = ProductProjectionSearch.ofCurrent() .withLimit(numProducts) .withQueryFilters(product -> product.categories().id().containsAny(categoryIds)) .withSort(product -> product.allVariants().price().desc()) .withPriceSelection(PriceUtils.createPriceSelection(userContext)); return sphereClient.execute(request) .whenCompleteAsync((result, t) -> logProductRequest(LOGGER, request, result), HttpExecution.defaultContext()) .thenApply(SunriseProductRecommendation::resultToProductSet); }
private static List<ProductProjection> searchForCategoryAndSort(final String categoryId) { final ProductProjectionSearch searchRequest = ProductProjectionSearch.ofStaged() .withQueryFilters(productModel -> productModel.categories().id().is(categoryId)) .withSort(productModel -> productModel.categoryOrderHints().category(categoryId).asc()); return client().executeBlocking(searchRequest).getResults(); }
@Test public void searchRequestIsAsExpected() { final ProductProjectionSearch actual = ProductProjectionSearchBuilder.ofCurrent() .facets(m -> m.allVariants().price().centAmount().allRanges()) .queryFilters(m -> m.allVariants().price().centAmount().isGreaterThanOrEqualTo(4L)) .sort(m -> m.createdAt().asc()) .expansionPaths(m -> m.categories()) .build(); final ProductProjectionSearch expected = ProductProjectionSearch.ofCurrent() .withFacets(m -> m.allVariants().price().centAmount().allRanges()) .withQueryFilters(m -> m.allVariants().price().centAmount().isGreaterThanOrEqualTo(4L)) .withSort(m -> m.createdAt().asc()) .withExpansionPaths(m -> m.categories()); assertThat(actual).isEqualTo(expected); } }