Skip to content

Latest commit

 

History

History
1346 lines (944 loc) · 63 KB

File metadata and controls

1346 lines (944 loc) · 63 KB
title date perex author proofreading preferredLang
Facet filtering
14.2.2025
Faceted filtering, also known as parameterized filtering, is a user interface feature that allows users to refine search results by applying multiple filters based on various properties or "facets" like category, parameter, or brand. Users can toggle these filters on or off to drill down into a data set interactively, essentially performing real-time complex queries without technical knowledge. The benefits are twofold: First, it improves user experience by enabling more targeted and efficient searching. Second, it can increase conversion rates for e-commerce sites by helping users quickly find and purchase products that meet their specific criteria.
Ing. Jan Novotný
done
evitaql

Facet filter example

The key success factor of faceted search is to help users avoid situations where their filter combination returns no results. It works best when we gradually limit the facet options that don't make sense with the ones already selected, and also provide accurate, on-the-spot, real-time feedback about the number of results that will expand or limit the current selection when another facet is selected.

Facets are usually displayed as a list of checkboxes, radio buttons, drop-down menus, or sliders, and are organized into groups. The options within a group usually expand the current selection (logical disjunction), and the groups are usually combined with logical conjunction. Some of the facets can be negated (logical negation) to exclude results that match the facet option.

High cardinality facets are sometimes presented in the form of a search box or interval slider (sometimes with a histogram of the distribution of values) to allow users to specify the exact value or range of values they are looking for.

evitaDB supports all of the above forms of facet search using the operators documented in this chapter and in histogram.

evitaLab visualization

If you want to get more familiar with the facet summary calculation, you can try to play with the query and see how it affects the visualization tab you can find in our evitaLab console:

Facet summary visualization in the evitaLab console

The visualization is organized in the same way as the facet summary itself:

Icon Meaning
Reference At the top level, you can see the links marked with the chain icon.
Facet group Below them are the groups found within these reference types, marked with the group icon, and finally below the groups are the facet options themselves.
Results matching facet Represents the number of entities returned that match this facet option when the user has no other facets selected (i.e., has an empty userFilter constraint).
Current number of results / difference when facet is selected Represents the current number of entities returned that match the filter constraints, next to the slash there is a difference in the number of results when this facet option is added to the user filter.
Total number of results with this facet selected Represents the total number of entities that will be displayed in the result when this facet option is selected (i.e., the number of entities that match the facet option in the entire dataset). )

Default facet calculation rules

  1. The facet summary is calculated only for entities that are returned in the current query result (excluding the effect of userFilter part of the query if present)
  2. The calculation respects any filter constraints placed outside the userFilter container.
  3. The default relation between facets within a group is logical disjunction (logical OR) unless you say otherwise.
  4. The default relation between facets in different groups / references is a logical conjuction (logical AND) unless you say otherwise.

You can change the default facet calculation relations by using the facetCalculationRules in the requirement part of your query.

Facet summary

facetSummary(
    argument:enum(COUNTS|IMPACT)?,
    filterConstraint:filterBy,
    filterConstraint:filterGroupBy,
    orderConstraint:orderBy,
    orderConstraint:orderGroupBy,
    requireConstraint:entityFetch,
    requireConstraint:entityGroupFetch
)
argument:enum(COUNTS|IMPACT)?

**Default:** `COUNTS`

    <p>optional argument of type <LS to="j,e,r,g"><SourceClass>evita_query/src/main/java/io/evitadb/api/query/require/FacetStatisticsDepth.java</SourceClass></LS><LS to="c"><SourceClass>EvitaDB.Client/Queries/Requires/FacetStatisticsDepth.cs</SourceClass></LS>
        that allows you to specify the computation depth of the facet summary:</p>

    <p>
    - **COUNTS**: each facet contains the number of results that match the facet option only
    - **IMPACT**: each non-selected facet contains the prediction of the number of results that would be returned
        if the facet option were selected (the impact analysis), this calculation is affected by the required
        constraints that change the default facet calculation behavior: [conjunction](#facet-groups-conjunction),
        [disjunction](#facet-groups-disjunction), [negation](#facet-groups-negation).
    </p>

</dd>
<dt>filterConstraint:filterBy</dt>
<dd>
    optional filter constraint that limits the facets displayed and calculated in the summary to those that match
    the specified filter constraint.
</dd>
<dt>filterConstraint:filterGroupBy</dt>
<dd>
    optional filter constraint that restricts the entire facet group whose facets are displayed and calculated in
    the summary to those that belong to the facet group matching the filter constraint.
</dd>
<dt>orderConstraint:orderBy</dt>
<dd>
    optional order constraint that specifies the order of the facet options within each facet group
</dd>
<dt>orderConstraint:orderGroupBy</dt>
<dd>
    optional order constraint that specifies the order of the facet groups
</dd>
<dt>requireConstraint:entityFetch</dt>
<dd>
    optional requirement constraint that allows you to fetch the referenced entity body; the `entityFetch`
    constraint can contain nested `referenceContent` with an additional `entityFetch` / `entityGroupFetch`
    constraints that allows you to fetch the entities in a graph-like manner to an "infinite" depth
</dd>
<dt>requireConstraint:entityGroupFetch</dt>
<dd>
    optional requirement constraint that allows you to fetch the referenced entity group body; the `entityGroupFetch`
    constraint can contain nested `referenceContent` with an additional `entityFetch` / `entityGroupFetch`
    constraints that allows you to fetch the entities in a graph-like manner to an "infinite" depth
</dd>
facetSummary(
    argument:enum(COUNTS|IMPACT),
    requireConstraint:entityFetch,
    requireConstraint:entityGroupFetch
)
argument:enum(COUNTS|IMPACT)

**Default:** `COUNTS`

    <p>optional argument of type <SourceClass>evita_query/src/main/java/io/evitadb/api/query/require/FacetStatisticsDepth.java</SourceClass>
        that allows you to specify the computation depth of the facet summary:</p>

    <p>
    - **COUNTS**: each facet contains the number of results that match the facet option only
    - **IMPACT**: each non-selected facet contains the prediction of the number of results that would be returned
        if the facet option were selected (the impact analysis), this calculation is affected by the required
        constraints that change the default facet calculation behavior: [conjunction](#facet-groups-conjunction),
        [disjunction](#facet-groups-disjunction), [negation](#facet-groups-negation).
    </p>

</dd>
<dt>requireConstraint:entityFetch</dt>
<dd>
    optional requirement constraint that allows you to fetch the referenced entity body; the `entityFetch`
    constraint can contain nested `referenceContent` with an additional `entityFetch` / `entityGroupFetch`
    constraints that allows you to fetch the entities in a graph-like manner to an "infinite" depth
</dd>
<dt>requireConstraint:entityGroupFetch</dt>
<dd>
    optional requirement constraint that allows you to fetch the referenced entity group body; the `entityGroupFetch`
    constraint can contain nested `referenceContent` with an additional `entityFetch` / `entityGroupFetch`
    constraints that allows you to fetch the entities in a graph-like manner to an "infinite" depth
</dd>

The request triggers the calculation of the evita_api/src/main/java/io/evitadb/api/requestResponse/extraResult/FacetSummary.javaEvitaDB.Client/Models/ExtraResults/FacetSummary.cs containing the facet summary calculation. The calculated facet summary will contain all entity references marked as faceted in the entity schema. The facet summary can be further modified by the facet summary of reference constraint, which allows you to override the general facet summary behavior specified in the generic facet summary require constraint.

The facet summary can be requested with the facetSummary field within extra results. This request triggers the calculation of the facet summary object, which contains the facet summary calculation. The calculated facet summary can contain all entity references marked as faceted in the entity schema. The facet summary calculation is requested separately for each reference, so each reference can have its own behaviour defined.

The faceted property affects the size of the indexes kept in memory and the scale / complexity of the general facet summary (i.e. the summary generated by the facetSummary request). It is recommended to mark only the references used for faceted filtering as faceted to keep the indexes small and the calculation of the facet summary in the user interface fast and simple. The combinatorial complexity of the facet summary is quite high for large datasets, and you may be forced to optimize it by narrowing the summary using the filtering facility or selecting only a few references for the summary.

Facet summary structure

The facet summary contains only entities referenced by entities returned in the current query response (excluding the effect of userFilter part of the query if present) and is organized in a three-tier structure:

1st tier: reference

For each entity reference marked as faceted in the facet summary, there is a separate data container for collection of the 2nd-tier facet groups. If the facets for this reference are not organized in groups (the reference lacks the group information), the facet summary will contain only one facet group named "non-grouped facets".

2nd tier: facet group

Facet group lists all facet options available for the given group and reference combination. It also contains a count of all entities in the current query result that match at least one facet in the group / reference. Optionally, it can contain the body of the group entity if the entityGroupFetch requirement is specified. Optionally, it can contain the body of the group entity if the groupEntity field is specified.

There may also be a special "group" for facets that are not related to a group. This group will be placed in the facet summary as a nonGroupedStatistics property. This group will be returned as a single group for the reference.

3rd tier: facet

Facet contains the statistics for that facet option:

count
It represents the number of all entities in the current query result (including user filter constraints) that have this facet (have reference to entity with this primary key).
requested
`TRUE` if this facet is requested in the [`user filter`](../filtering/behavioral.md#user-filter) container of this query, `FALSE` otherwise (this property allows you to easily mark the facet checkbox as checked in the user interface).
And optionally the body of the facet (referenced) entity if the [`entityFetch`](#entity-fetch) requirement is specified. If the `IMPACT` statistics depth is requested in the facet summary, the statistics will also include the impact analysis calculation, which contains the following data: And optionally the body of the facet (referenced) entity if the `facetEntity` field is specified. If the `impact` object is requested in the facet summary, the statistics will also include the impact analysis calculation, which can contains the following data:
matchCount
It represents the number of all entities that would match a new query derived from the current query if this particular facet option were selected (has reference to entity with this primary key). The current query is left intact, including the [`user filter`](../filtering/behavioral.md#user-filter) part, but a new facet query is virtually added to the user filter to calculate the hypothetical impact of selecting the facet option.
difference
It represents the difference between the `matchCount` (hypothetical result should this facet be selected) and the current number of entities returned. It represents the size of the impact on the current result. It can be either positive (the facet option would expand the current result) or negative (the facet option would limit the current result). The difference can be `0` if the facet option doesn't change the current result.
hasSense
`TRUE` if the facet option combined with the current query still returns some results (matchCount > 0), `FALSE` otherwise. This property allows you to easily mark the facet checkbox as "disabled" in the user interface.

The evita_query/src/main/java/io/evitadb/api/query/require/FacetSummary.javaEvitaDB.Client/Queries/Requires/FacetSummary.cs requirement triggers the calculation of the evita_api/src/main/java/io/evitadb/api/requestResponse/extraResult/FacetSummary.javaEvitaDB.Client/Models/ExtraResults/FacetSummary.cs extra result. The facet summary is always computed as a side result of the main entity query and respects any filtering constraints placed on the queried entities. To demonstrate the facet summary calculation, we will use the following example:

Facet summary calculation for products in "e-readers" category

When the facetSummary field is specified with specific references within the extraResults field is specified, it triggers the calculation of the facet summary extra result. The facet summary is always computed as a side result of the main entity query, and respects any filter constraints placed on the queried entities. To demonstrate the facet summary calculation, we will use the following example:

Facet summary calculation for products in "e-readers" category

The result of the facet summarization in the "e-readers" category

The query returns a list of "active" products in the "e-readers" category, and in the extra results index it also includes the facet summary calculation:

The result of the facet summarization in the "e-readers" category

The result of the facet summarization in the "e-readers" category

The result of the facet summarization in the "e-readers" category

The format has been simplified because the raw JSON result would be too long and hard to read. This is the output format of the prettyPrint method of evita_api/src/main/java/io/evitadb/api/requestResponse/extraResult/FacetSummary.java and you can see the summary organized in a three-tier structure, along with the information about the number of result entities for each of the facets and facet groups. No facet is currently selected and therefore the lead [ ] is not checked anywhere. The listing doesn't contain any human-readable information except the primary keys of the references, facet groups, and facets - to get them we would have to add their bodies.

You can see the summary organized in a three-tier structure, along with the information about the number of result entities for each of the facets and facet groups. No facet is currently selected and therefore the requested property is false everywhere. The listing doesn't contain any human-readable information except the primary keys of the references, facet groups, and facets - to get them we would have to add their bodies.

Fetching facet (group) bodies

The facet summary makes little sense without the bodies of the facet groups and facets. To get those bodies, you need to add entityFetch or entityGroupFetch requirement to the query. Let's modify the example to fetch the facet summary along with the codes of the facets and their groups:

The facet summary makes little sense without the bodies of the facet groups and facets. To get those bodies, you need to request facetEntity or groupEntity fields. Let's modify the example to fetch the facet summary along with the codes of the facets and their groups:

Facet summary calculation with bodies for products in "e-readers" category

Facet summary calculation with bodies for products in "e-readers" category

The result of the facet summarization in the "e-readers" category including the referenced entity bodies

Now you can see that the facet summary contains not only the primary keys, but also the somewhat comprehensible codes of the facets and their respective groups:

The result of the facet summarization in the "e-readers" category including the referenced entity bodies

The result of the facet summarization in the "e-readers" category including the referenced entity bodies

The result of the facet summarization in the "e-readers" category including the referenced entity bodies

If you add the desired locale to the query and also list localized names, you'll get a result that's very close to the version you want to see in the user interface:

Facet summary calculation with localized names for products in the "e-readers" category

Facet summary calculation with localized names for products in the "e-readers" category

The result of facet summary with localized names for products in the "e-readers" category

The result of facet summary with localized names for products in the "e-readers" category

The result of facet summary with localized names for products in the "e-readers" category

Filtering facet summary

The facet summary sometimes gets very big, and besides the fact that it is not very useful to show all facet options in the user interface, it also takes a lot of time to calculate it. To limit the facet summary, you can use the filterBy and filterGroupBy (which is the same as filterBy, but it filters the entire facet group instead of individual facets) constraints.

The filterGroupBy can be specified on each reference field returning facet groups. The filterBy can be specified deeper in the facet summary structure, specifically within the group definition on the facetStatistics field, which returns the actual facet options.

If you add the filtering constraints to the facetSummary requirement, you can only refer to filterable properties that are shared by all referenced entities. This may not be feasible in some cases, and you will need to split the generic facetSummary requirement into multiple individual facetSummaryOfReference requirements with specific filters for each reference type.

Behaviour of filtering on referenced entities in facet summary constraint

It's hard to find a good example for filtering a generic facet summary even for our demo dataset, so the example will be a bit artificial. Let's say we want to display only the facet options whose code attribute contains the substring ar, and only those that are within groups with code starting with the letter o:

Filtering facet summary options

Filtering facet summary options

The result of facet summary filtering

We don't limit the search to a specific hierarchy because the filter is quite selective, as you can see in the result:

The result of facet summary filtering

The result of facet summary filtering

Ordering facet summary

Ordering facet summary

The `orderGroupBy` can be specified on each reference field returning facet groups. The `orderBy` can be specified deeper in the facet summary structure, specifically inside the group definition on `facetStatistics` field returning actual facet options.

If you add the ordering constraints to the facetSummary requirement, you can only refer to sortable properties that are shared by all referenced entities. This may not be feasible in some cases, and you will need to split the generic facetSummary requirement into multiple individual facetSummaryOfReference requirements with specific ordering constraints for each reference type.

Behaviour of ordering on referenced entities in facet summary constraint

Let's sort both facet groups and facets alphabetically by their English names:

Sort facet summary options

Sort facet summary options

The result of facet summary sorting

You can see that the facet summary is now sorted where appropriate:

The result of facet summary sorting

The result of facet summary sorting

The result of facet summary sorting

Facet summary of reference

facetSummaryOfReference(
    argument:string!,
    argument:enum(COUNTS|IMPACT),
    filterConstraint:filterBy,
    filterConstraint:filterGroupBy,
    orderConstraint:orderBy,
    orderConstraint:orderGroupBy,
    requireConstraint:entityFetch,
    requireConstraint:entityGroupFetch
)
argument:string!
mandatory argument specifying the name of the [reference](../../use/schema.md#reference) that is requested by this constraint, the reference must be marked as `faceted` in the [entity schema](../../use/schema.md)
argument:enum(COUNTS|IMPACT)

**Default:** `COUNTS`

    <p>optional argument of type <LS to="e,j,r"><SourceClass>evita_query/src/main/java/io/evitadb/api/query/require/FacetStatisticsDepth.java</SourceClass></LS><LS to="c"><SourceClass>EvitaDB.Client/Queries/Requires/FacetStatisticsDepth.cs</SourceClass></LS>
        that allows you to specify the computation depth of the facet summary:</p>

    <p>
    - **COUNTS**: each facet contains the number of results that match the facet option only
    - **IMPACT**: each non-selected facet contains the prediction of the number of results that would be returned
        if the facet option were selected (the impact analysis), this calculation is affected by the required
        constraints that change the default facet calculation behavior: [conjunction](#facet-groups-conjunction),
        [disjunction](#facet-groups-disjunction), [negation](#facet-groups-negation).
    </p>
</dd>
<dt>filterConstraint:filterBy</dt>
<dd>
    optional filter constraint that limits the facets displayed and calculated in the summary to those that match
    the specified filter constraint.
</dd>
<dt>filterConstraint:filterGroupBy</dt>
<dd>
    optional filter constraint that restricts the entire facet group whose facets are displayed and calculated in
    the summary to those that belong to the facet group matching the filter constraint.
</dd>
<dt>orderConstraint:orderBy</dt>
<dd>
    optional order constraint that specifies the order of the facet options within each facet group
</dd>
<dt>orderConstraint:orderGroupBy</dt>
<dd>
    optional order constraint that specifies the order of the facet groups
</dd>
<dd>
    optional requirement constraint that allows you to fetch the referenced entity body; the `entityFetch`
    constraint can contain nested `referenceContent` with an additional `entityFetch` / `entityGroupFetch`
    constraints that allows you to fetch the entities in a graph-like manner to an "infinite" depth
</dd>
<dt>requireConstraint:entityGroupFetch</dt>
<dd>
    optional requirement constraint that allows you to fetch the referenced entity group body; the `entityGroupFetch`
    constraint can contain nested `referenceContent` with an additional `entityFetch` / `entityGroupFetch`
    constraints that allows you to fetch the entities in a graph-like manner to an "infinite" depth
</dd>

The evita_query/src/main/java/io/evitadb/api/query/require/FacetSummaryOfReference.javaEvitaDB.Client/Queries/Requires/FacetSummaryOfReference.cs requirement triggers the calculation of the evita_api/src/main/java/io/evitadb/api/requestResponse/extraResult/FacetSummary.javaEvitaDB.Client/Models/ExtraResults/FacetSummary.cs for a specific reference. When a generic facetSummary requirement is specified, this require constraint overrides the default constraints from the generic requirement to constraints specific to this particular reference. By combining the generic facetSummary and facetSummaryOfReference, you define common requirements for the facet summary calculation, and redefine them only for references where they are insufficient. The facetSummaryOfReference requirements redefine all constraints from the generic facetSummary requirement.

Let's say we want to display the facet summary for products in the e-readers category, but we want the summary to be computed only for the brand and parameterValues references. The facets within the brand reference should be ordered by name in alphabetical order, and the facets within the parameterValues reference should be ordered by their order attribute, both at the group level and at the facet level. Only the facets inside facet groups (parameter) with isVisible attribute equal to TRUE should be calculated for the summary:

Calculate facet summary for selected references

The result of facet summarization of named references

As you can see, this is a fairly complex scenario that uses all the key features of the facet summary calculation:

The result of facet summarization of named references

The result of facet summarization of named references

Filtering facet summary

The facet summary sometimes gets very big, and besides the fact that it is not very useful to show all facet options in the user interface, it also takes a lot of time to calculate it. To limit the facet summary, you can use the filterBy and filterGroupBy (which is the same as filterBy, but it filters the entire facet group instead of individual facets) constraints.

You can only filter facets and groups using facetSummaryOfReference because a filter container is specific to a particular entity collection, which is not known in advance in the generic facetSummary.

Behaviour of filtering on referenced entities in facet summary constraint

It's hard to find a good example for filtering a generic facet summary even for our demo dataset, so the example will be a bit artificial. Let's say we want to display only the facet options whose code attribute contains the substring ar, and only those that are within groups with code starting with the letter o:

Filtering facet summary options

The result of facet summary filtering

We don't limit the search to a specific hierarchy because the filter is quite selective, as you can see in the result:

The result of facet summary filtering

Ordering facet summary

Ordering facet summary

You can only sort facets and groups using facetSummaryOfReference because a filter container is specific to a particular entity collection, which is not known in advance in the generic facetSummary.

Behaviour of ordering on referenced entities in facet summary constraint

Let's sort both facet groups and facets alphabetically by their English names:

Sort facet summary options

The result of facet summary sorting

You can see that the facet summary is now sorted where appropriate:

The result of facet summary sorting

Entity group fetch

The entityGroupFetch constraint used within the facetSummary or facetSummaryOfReference requirement is identical to the entityFetch requirement described in the referenced chapter. The only difference is that the entityGroupFetch refers to the related group entity schema specified by the faceted reference schema, and is named entityGroupFetch instead of entityFetch to distinguish the requirements for referenced (facet) entity and referenced (facet) entity group.

The groupEntity field used within the facet group object in the facetSummary has same meaning as standard entity fetching. The only difference is that the groupEntity refers to the related group entity schema specified by the faceted reference schema.

Entity fetch

The entityFetch constraint used within the facetSummary or facetSummaryOfReference requirement is identical to the entityFetch requirement described in the referenced chapter. The only difference is that the entityFetch refers to the related entity schema specified by the faceted reference schema.

The facetEntity field used within the facet object in the facetSummary has same meaning as standard entity fetching. The only difference is that the facetEntity refers to the related entity schema specified by the faceted reference schema.

Facet groups conjunction

facetGroupsConjunction(
    argument:string!,
    argument:enum(WITH_DIFFERENT_FACETS_IN_GROUP|WITH_DIFFERENT_GROUPS),
    filterConstraint:filterBy
)
argument:string!
Mandatory argument specifying the name of the [reference](../../use/schema.md#reference) to which this constraint refers.
argument:enum(WITH_DIFFERENT_FACETS_IN_GROUP|WITH_DIFFERENT_GROUPS)

**Default: `WITH_DIFFERENT_FACETS_IN_GROUP`**

Optional enumeration argument specifying whether the relationship type should be applied to facets at a particular level (within the same facet group, or to facets in different facet groups/references).

filterConstraint:filterBy
Optional filter constraint that selects one or more facet groups whose facets will be combined with logical AND instead of the default logical OR.
    If the filter is not defined, the behavior applies to all groups of a given reference in the facet summary.
</dd>

The evita_query/src/main/java/io/evitadb/api/query/require/FacetGroupsConjunction.javaEvitaDB.Client/Queries/Requires/FacetGroupsConjunction.cs changes the default behavior of the facet summary calculation for the facet groups specified in the filterBy constraint. Instead of the default relationship (either system defaults or overridden defaults), the facet options in the facet groups at a given level are combined with a logical AND.

Behaviour of filtering on referenced entities in facet groups conjunction constraint

To understand the difference between the default behavior and the behavior of this requirement, let's compare the facet summary calculation for the same query with and without this requirement. We will need a query that targets some reference (let's say groups) and pretend that the user has already requested (checked) some of the facets. If we now want to calculate the IMPACT analysis for the rest of the facets in the group, we will see that changing the default behavior changes the numbers produced:

Facet groups conjunction example

Note that the facetGroupsConjunction in the example doesn't contain a filterBy constraint, so it applies to all the facet groups in the facet summary, or in this particular case to facets in the reference groups that are not part of any group. Also we don't specify a level, so it defaults to WITH_DIFFERENT_FACETS_IN_GROUP.

Default behaviour Altered behaviour
Before After
The result of facet summarization with inverted facet relation behavior

You can see that instead of increasing the number of results in the final set, the impact analysis predicts their reduction:

The result of facet summarization with inverted facet relation behavior

The result of facet summarization with inverted facet relation behavior

The result of facet summarization with inverted facet relation behavior

Facet groups disjunction

facetGroupsDisjunction(
    argument:string!,
    argument:enum(WITH_DIFFERENT_FACETS_IN_GROUP|WITH_DIFFERENT_GROUPS),
    filterConstraint:filterBy
)
argument:string!
Mandatory argument specifying the name of the [reference](../../use/schema.md#reference) to which this constraint refers.
argument:enum(WITH_DIFFERENT_FACETS_IN_GROUP|WITH_DIFFERENT_GROUPS)

**Default: `WITH_DIFFERENT_FACETS_IN_GROUP`**

Optional enumeration argument specifying whether the relationship type should be applied to facets at a particular level (within the same facet group, or to facets in different facet groups/references).

filterConstraint:filterBy
Optional filter constraint that selects one or more facet groups whose facet options will be combined with logical disjunction (logical OR) with facets of different groups instead of the default logical conjunction (logical AND).
    If the filter is not defined, the behavior applies to all groups of a given reference in the facet summary.
</dd>

The evita_query/src/main/java/io/evitadb/api/query/require/FacetGroupsDisjunction.javaEvitaDB.Client/Queries/Requires/FacetGroupsDisjunction.cs changes the default behavior of the facet summary calculation for the facet groups specified in the filterBy constraint. Instead of the default relationship (either system defaults or overridden defaults), the facet options in the facet groups at a given level are combined with a logical OR.

Behaviour of filtering on referenced entities in facet groups disjunction constraint

To understand the difference between the default behavior and the behavior of this constraint, let's compare the facet summary calculation for the same query with and without this constraint. We will need a query that targets some reference (let's say parameterValues) and pretend that the user has already requested (checked) some of the facets. Now, if we want to calculate the IMPACT analysis for the other group in the facet summary, we will see that instead of reducing the numbers, the impact analysis predicts their expansion:

Facet groups disjunction example

Default behaviour Altered behaviour
Before After
The result of facet summarization with inverted facet group relation behavior

You can see that instead of reducing the number of results in the final set, the impact analysis predicts their expansion:

The result of facet summarization with inverted facet group relation behavior

The result of facet summarization with inverted facet group relation behavior

The result of facet summarization with inverted facet group relation behavior

Facet groups negation

facetGroupsNegation(
    argument:string!,
    argument:enum(WITH_DIFFERENT_FACETS_IN_GROUP|WITH_DIFFERENT_GROUPS),
    filterConstraint:filterBy
)
argument:string!
Mandatory argument specifying the name of the [reference](../../use/schema.md#reference) to which this constraint refers.
argument:enum(WITH_DIFFERENT_FACETS_IN_GROUP|WITH_DIFFERENT_GROUPS)

**Default: `WITH_DIFFERENT_FACETS_IN_GROUP`**

Optional enumeration argument specifying whether the relationship type should be applied to facets at a particular level (within the same facet group, or to facets in different facet groups/references).

filterConstraint:filterBy
Optional filter constraint that selects one or more facet groups whose facet options are negated. Thus, instead of returning only those items that reference that particular faceted entity, the query result will return only those items that don't reference it.
    If the filter is not defined, the behavior applies to all groups of a particular reference in the facet summary.
</dd>

The evita_query/src/main/java/io/evitadb/api/query/require/FacetGroupsNegation.javaEvitaDB.Client/Queries/Requires/FacetGroupsNegation.cs changes the behavior of the facet option in all facet groups specified in the filterBy constraint. Instead of returning only those items that have a reference to that particular faceted entity, the query result will return only those items that don't have a reference to it.

As long as you leaf the other argument on system default it doesn't matter if you set NEGATION for the level within the same facet group or between different groups, because by the De Morgan's las the result will be the same (!a && !b is the equivalent to !(a || b)).

Behaviour of filtering on referenced entities in facet groups negation constraint

To demonstrate this effect, we need a query that targets some reference (let's say parameterValues) and makes some of the listed group as negated.

Facet groups disjunction example

Default behaviour Altered behaviour
Before After
The result of facet summarization with negated facet relation behavior in the group

The predicted results in the negated groups are far greater than the numbers produced by the default behavior. As you can see, selecting any option in the RAM facet group predicts returning thousands of results, while the ROM facet group with default behavior predicts only a dozen of them:

The result of facet summarization with negated facet relation behavior in the group

The result of facet summarization with negated facet relation behavior in the group

The result of facet summarization with negated facet relation behavior in the group

Facet groups exclusivity

facetGroupsExclusivity(
    argument:string!,
    argument:enum(WITH_DIFFERENT_FACETS_IN_GROUP|WITH_DIFFERENT_GROUPS),
    filterConstraint:filterBy
)
argument:string!
Mandatory argument specifying the name of the [reference](../../use/schema.md#reference) to which this constraint refers.
argument:enum(WITH_DIFFERENT_FACETS_IN_GROUP|WITH_DIFFERENT_GROUPS)

**Default: `WITH_DIFFERENT_FACETS_IN_GROUP`**

Optional enumeration argument specifying whether the relationship type should be applied to facets at a particular level (within the same facet group, or to facets in different facet groups/references).

filterConstraint:filterBy
Optional filter constraint that selects one or more facet groups whose facet options are mutually exclusive.
    If the filter is not defined, the behavior applies to all groups of a particular reference in the facet summary.
</dd>

The evita_query/src/main/java/io/evitadb/api/query/require/FacetGroupsExclusivity.javaEvitaDB.Client/Queries/Requires/FacetGroupsExclusivity.cs changes the behavior of the facet option in all facet groups specified in the filterBy constraint. This relationship doesn't affect the query output. It's up to the client to ensure that only one facet is selected at a given level. If the client provides more than one facet at a particular level, the system will use system defaults for the calculation (i.e. logical OR for facets within the same facet group and logical AND for facets between different groups).

The impact statistics will be calculated for the situation where only this particular facet is selected and no others in the same group / in different groups are selected.

Since this operator doesn't affect the actual result set output, it can only be used for the specific impact calculation, if you want to see the impact of selecting only one facet at a particular level.

To demonstrate this effect, we need a query that targets some reference (let's say parameterValues) and makes some of the listed group as exclusive.

Facet groups exclusivity example

Default behaviour Altered behaviour
Before After
The result of facet summarization with exclusive facet relation behavior in the group

The predicted results in the exclusive groups are different for the numbers produced by the default behaviour when there is an existing facet selection used for the current query. As you can see, the current selection of the option in the RAM facet group doesn't affect the predicted counts (they remain the same as if no selection had been made):

The result of facet summarization with exclusive facet relation behavior in the group

The result of facet summarization with exclusive facet relation behavior in the group

The result of facet summarization with exclusive facet relation behavior in the group

Facet calculation rules

facetCalculationRules(
    argument:enum(DISJUNCTION|CONJUNCTION|NEGATION|EXCLUSIVITY)!,
    argument:enum(DISJUNCTION|CONJUNCTION|NEGATION|EXCLUSIVITY)!
)
argument:enum(DISJUNCTION|CONJUNCTION|NEGATION|EXCLUSIVITY)!
Mandatory argument specifying the default relationship behaviour for facets within the same facet group. You can change the default logical disjunction (logical OR) to a different value.
argument:enum(DISJUNCTION|CONJUNCTION|NEGATION|EXCLUSIVITY)!
Mandatory argument specifying the default relationship behaviour for the facets between different facet groups or references. You can change the default logical operator (logical AND) to a different value.

The evita_query/src/main/java/io/evitadb/api/query/require/FacetCalculationRules.javaEvitaDB.Client/Queries/Requires/FacetCalculationRules.cs requirement changes the default behavior of the facet summary calculation to the specified logical operators. The first argument specifies the default relationship behavior for facets within the same facet group, and the second argument specifies the default relationship behavior for the facets between different facet groups or references.

Supported logical operators:

DISJUNCTION
Logical OR operator.
    Effect on [facet having behavior](../filtering/references.md#facet-having): entity will be present in the result
    set once it has at least one of the selected facets at a particular level (within the same facet group / between different groups).

    Effect on [impact statistics](#3rd-tier-facet): logical OR will likely extend the number of results in the final 
    set.
</dd>
<dt>CONJUNCTION</dt>
<dd>
    Logical AND operator.

    Effect on [facet having behavior](../filtering/references.md#facet-having): entity will be present in the result
    set once it has all the selected facets at a particular level (within the same facet group / between different groups).

    Effect on [impact statistics](#3rd-tier-facet): logical AND will likely reduce the number of results in the final 
    set.
</dd>
<dt>NEGATION</dt>
<dd>
    Logical AND NOT operator.

    Effect on [facet having behavior](../filtering/references.md#facet-having): entity will be present in the result
    set once it has none the selected facets at a particular level. As long as you leaf the other argument on system 
    default it doesn't matter if you set NEGATION for the level within the same facet group or between different groups,
    because by the [De Morgan's las](https://en.wikipedia.org/wiki/De_Morgan%27s_laws) the result will be the same
    (`!a && !b` is the equivalent to `!(a || b)`).

    Effect on [impact statistics](#3rd-tier-facet): logical AND NOT will likely extend the number of results in the 
    final set if the entities have only a few facets of all the possible ones on average.
</dd>
<dt>EXCLUSIVITY</dt>
<dd>
    Special logical operator that says that only one facet can be selected at a given level (within the same facet 
    group / between different groups). This is useful for facets that are mutually exclusive.

    Effect on [facet having behaviour](../filtering/references.md#facet-having): none - it's up to the client to 
    ensure that only one facet is selected at a given level. If the client provides more than one facet at 
    a particular level, the system will use system defaults for the calculation (i.e. logical OR for facets within 
    the same facet group and logical AND for facets between different groups).

    Effect on [impact statistics](#3rd-tier-facet): The calculated match count and impact will be calculated for 
    the situation where only this particular facet is selected and no others in the same group / in different groups 
    are selected.

    **Note**: since this operator doesn't affect the actual result set output, it can only be used for the specific 
    impact calculation, if you want to see the impact of selecting only one facet at a particular level.
</dd>

Changing the default facet calculation rules is similar to configuring each individual facet group relationship using requirement constraints:

The sample query that changes the default calculation rules is as follows

Changing default calculation rules example