io.sphere.sdk.meta.SearchDocumentation Maven / Gradle / Ivy
package io.sphere.sdk.meta;
import io.sphere.sdk.models.Base;
/** Products can be retrieved using full-text search, filtering, faceting and sorting functionality combined.
Even though the {@link io.sphere.sdk.meta.QueryDocumentation Query API} lets you query for resources with certain attribute values, its performance is seriously affected by some attributes, specially by custom attributes, when manipulating data (i.e. filtering, sorting). Moreover, some typical operations over a list of resources, such as full-text search and facets, are simply not supported.
The Search API is specially designed to support those uses cases where the Query API is not powerful enough, by providing not only full-text search, filtering, and sorting, but also statistical analysis of the data with facets.
The search endpoints are supposed to be faster than the query endpoints, but for the price of eventual consistency. In other words, whenever the name of a product was changed, it will still take some seconds to propagate this change to the search index.
Currently only products have a search endpoint for {@link io.sphere.sdk.products.ProductProjection} only. Therefore, be aware that the class to create a search request for products is called {@link io.sphere.sdk.products.search.ProductProjectionSearch}.
The following examples in this document are based on the search for products. The product data defined in the SPHERE.IO platform used for the following code examples are:
Product
Product1 "shoe"
Product2 "shirt"
Product3 "dress"
Variant
1
2
1
2
1
2
Color
blue
red
blue
Size
38
46
36
44
40
42
Full Text Search
With {@link io.sphere.sdk.products.search.ProductProjectionSearch} you can perform a full-text search for a specific language. On the Full-Text Search documentation page you can explore which fields are included for the search and other additional information.
The following example uses {@link io.sphere.sdk.search.SearchDsl#withText(java.util.Locale, String)} to search for all products containing the word "shoe" in English:
{@include.example io.sphere.sdk.products.search.ProductProjectionSearchMainIntegrationTest#searchByTextInACertainLanguage()}
Pagination
Use {@link io.sphere.sdk.search.SearchDsl#withOffset(long)} and {@link io.sphere.sdk.search.SearchDsl#withLimit(long)} for pagination. An extended explanation about how pagination works in SPHERE.IO can be found in {@link io.sphere.sdk.meta.QueryDocumentation}.
The following request skips the first 50 products and limits the result set to only 25 products:
{@include.example io.sphere.sdk.products.search.ProductProjectionSearchMainIntegrationTest#paginationExample()}
Sorting
Any attribute you can sort by, allows both sort directions, ascending and descending. On the Sorting documentation page you can explore for which fields you can sort for. Use {@link io.sphere.sdk.products.search.ProductProjectionSortSearchModel} class to build sort expressions easily.
The code sample below shows a request for all products which will be sorted by size in an ascending direction:
{@include.example io.sphere.sdk.products.search.ProductProjectionSearchSortIntegrationTest#sortByAttributeAscending()}
When sorting on multi-valued attributes, such as attributes from product variants, you can also choose which value should be used for sorting. By default, the value selected is the best-matching according to the sorting direction, or in other words, the minimum value for ascending and the maximum value for descending sort. This behaviour can be easily inverted, as explained in the Sorting by Attributes documentation page.
In the following example the products are sorted by size in an ascending direction, but sorted using the highest size value within each product variants instead:
{@include.example io.sphere.sdk.products.search.ProductProjectionSearchSortIntegrationTest#sortWithAdditionalParameterByAttributeAscending()}
Alternatively, you can provide the sort request directly, even though this method is unsafe and therefore not recommended.
Here is the alternative code equivalent to the previous sorting by size:
{@include.example io.sphere.sdk.products.search.ProductProjectionSearchSortIntegrationTest#sortWithSimpleExpression()}
Providing a list of sort expressions has the effect of multi-sorting, as it is demonstrated in the following example:
{@include.example io.sphere.sdk.products.search.ProductProjectionSearchSortIntegrationTest#sortByMultipleAttributes()}
Faceting
Expressions
Facets calculate statistical counts based on the values associated with an attribute. Building facet expressions is very easy thanks to the {@link io.sphere.sdk.products.search.ProductProjectionFacetSearchModel} class. You can consult the Facets HTTP API documentation for more information.
There are three types of facets: {@link io.sphere.sdk.search.TermFacetResult}, {@link io.sphere.sdk.search.RangeFacetResult} and {@link io.sphere.sdk.search.FilteredFacetResult}. Next are presented example codes of each type to better illustrate how these facet types work.
The Term Facet result obtained with the following code contains all different size values found in the products, along with the statistical count of the amount of product variants with that value associated:
{@include.example io.sphere.sdk.products.search.ProductProjectionSearchFacetsIntegrationTest#termFacetsAreParsed()}
In contrast, the Filtered Facet result contains the statistical count for some certain values specified in the request, in this case the amount of variants with blue color:
{@include.example io.sphere.sdk.products.search.ProductProjectionSearchFacetsIntegrationTest#filteredFacetsAreParsed()}
You can also request statistics (i.e. count, minimum and maximum values, as well as the sum and arithmetic mean) about a range of values, like it is done with size in the following example within the range [0, +∞):
{@include.example io.sphere.sdk.products.search.ProductProjectionSearchFacetsIntegrationTest#rangeFacetsAreParsed()}
There is also the possibility to provide the facet expression directly, although it is unsafe and thus not recommended.
In the following code the same request as in the Term Facet example is reproduced, but providing a facet expression now instead:
{@include.example io.sphere.sdk.products.search.ProductProjectionSearchFacetsIntegrationTest#simpleFacetsAreParsed()}
Alias
Additionally, facets allow to specify an alias which will then replace the attribute path in the result. This functionality allows to calculate different types of facets on the same attribute. There is an extended explanation with examples in the API documentation for Facets.
In order to use it, the SDK offers a method that allows to define the desired alias:
{@include.example io.sphere.sdk.products.search.ProductProjectionSearchFacetsIntegrationTest#termFacetsSupportsAlias()}
Filtering
Types
When searching for products, there are three stages of the process where filters can be applied, as shown in the following drawing:
- Filter Query: {@link io.sphere.sdk.search.FilterDsl#withQueryFilters(java.util.List)}.
- This parameter allows to filter products BEFORE facets have been calculated, therefore this scope affects both results and facets.
- Filter Results (in the HTTP API it is called just "filter"): {@link io.sphere.sdk.search.FilterDsl#withResultFilters(java.util.List)}
- This parameter allows to filter products AFTER facets have been calculated, therefore this scope affects the results only. Using this filter only makes sense when used together with facets, otherwise Filter Query should be preferred for performance reasons.
- Filter Facets: {@link io.sphere.sdk.search.FilterDsl#withFacetFilters(java.util.List)}
- This parameter allows to filter those products used for facets calculation only, without affecting the results whatsoever. All facet calculations are affected except for those facets operating on the same field as the filter, enabling faceted search when combined with Filter Results.
Does it filter results?
Does it filter facets?
Filter Query
Yes
Yes
Filter Results
Yes
No
Filter Facets
No
Yes
No filter
No
No
For further explanation, some diagrams regarding the filter mechanism can be found in the Filters and Facets presentation.
Expressions
You can easily build filter expressions with the {@link io.sphere.sdk.products.search.ProductProjectionFilterSearchModel} class. For more details, check the HTTP API documentation for Filters.
In the following example only the products with red color are returned:
{@include.example io.sphere.sdk.products.search.ProductProjectionSearchFiltersIntegrationTest#filtersByTerm()}
Besides filtering by terms, you can also filter by a range of values, as shown in the following code.
Here we are requesting only those products with at least one variant having the size attribute greater than or equals to 44:
{@include.example io.sphere.sdk.products.search.ProductProjectionSearchFiltersIntegrationTest#filtersByRange()}
There is also the possibility to provide the filter expression directly, although it is unsafe and thus not recommended.
In the following example the same filter by size is requested as previously, but now in this way:
{@include.example io.sphere.sdk.products.search.ProductProjectionSearchFiltersIntegrationTest#simpleFilterByRange()}
Product Projection Search Model
The Search Model for products is currently in an experimental status, so please be aware it will probably suffer breaking changes in the future.
The {@link io.sphere.sdk.products.search.ProductProjectionSearchModel} class offers a domain-specific language (DSL) to build expressions accepted by the search endpoint, which can be otherwise a bit complex to write. In particular, this DSL allows you to build expressions for sorting, filtering and faceting, as it is demonstrated in the corresponding sections.
In order to build an expression, first you will be required to select the action to apply (i.e. {@link io.sphere.sdk.products.search.ProductProjectionSearchModel#filter}, {@link io.sphere.sdk.products.search.ProductProjectionSearchModel#facet} and {@link io.sphere.sdk.products.search.ProductProjectionSearchModel#sort}).
Then you need to build the path of the attribute you want to apply that action to, for example {@link io.sphere.sdk.products.search.ProductDataFilterSearchModel#lastModifiedAt} represents the {@code lastModifiedAt} attribute on a product. In the case of custom attributes, you also need to provide the attribute name and select the primary type of the attribute.
Finally, you need to indicate the criteria used for the desired operation. For example you would use {@link io.sphere.sdk.search.model.TermFilterSearchModel#byAny} if you want to filter by any of the given values.
Notice that even though the Search Model expects values of a certain type based on the attribute, you can force it to accept simple strings as shown in the following example:
{@include.example io.sphere.sdk.products.search.ProductProjectionSearchFiltersIntegrationTest#filterByValueAsString}
*/
public final class SearchDocumentation extends Base {
private SearchDocumentation() {
}
}