Reference filtering is used to filter entities based on their references to other entities in the catalog or
attributes specified in those relations.
Reference having
argument:string!
the name of the entity reference that will be subjected to the filtering
constraints in the second and subsequent arguments
filterConstraint:any+
one or more filter constraints that must be satisfied by one of the entity references with name specified in
the first argument
The
constraint
eliminates entities which has no reference of particular name satisfying set of filtering constraints. You can examine
either the attributes specified on the relation itself, wrap the filtering constraint
in entityHaving constraint to examine the attributes of the referenced entity,
or in groupHaving constraint to examine the attributes of the group entity associated
with the reference. The constraint is similar to
SQL EXISTS operator.
To demonstrate how the referenceHaving constraint works, let's query for products that have at least one alternative
product specified. The alternative products are stored in the relatedProducts reference on the Product entity and
have the category attribute set to alternativeProduct. There can be different types of related products other than
alternative products, for example spare parts and so on - that's why we need to specify the category attribute in
the filtering constraint.
Returns the following result:
If we wanted to query for products that have at least one related product reference of any category type, we could use
the following simplified query:
Which returns the following result:
Another frequently used use-case is to query for entities that have at least one reference to another entity with
certain primary key. For example, we want to query for products that are related to brand with primary key 66465.
This can be achieved by following query:
Which returns the following result:
Entity having
filterConstraint:any+
one or more filter constraints that must be satisfied by the target referenced entity of any of the source
entity references identified by the parent referenceHaving constraint
The entityHaving constraint is used to examine the attributes or other filterable properties of the referenced entity.
It can only be used within the referenceHaving constraint, which defines the name of the entity
reference that identifies the target entity to be subjected to the filtering restrictions in the entityHaving
constraint. The filtering constraints for the entity can use entire range
of filtering operators.
Let's use our previous example to query for products that relate to brand with particular attribute code:
Which returns the following result:
Group having
filterConstraint:any+
one or more filter constraints that must be satisfied by the group entity of any of the source
entity references identified by the parent referenceHaving constraint
The
constraint
is used to examine the attributes or other filterable properties of the group entity associated with a reference.
It can only be used within the referenceHaving constraint, which defines the name of the entity
reference whose group entity is subjected to the filtering restrictions in the groupHaving constraint. The filtering
constraints for the group entity can use the entire range of filtering operators.
This constraint requires the reference to be configured with a group type and to have the REFERENCED_GROUP_ENTITYindexed component enabled. The three sibling constraints address different
"layers" of a single reference and can be combined freely inside referenceHaving:
In the demo dataset, the parameterValues reference points to a ParameterValue entity (e.g. RAM 16 GB) and is
grouped by a Parameter entity (e.g. RAM memory). To find MacBooks that expose the RAM memory parameter at
all — regardless of how much memory each one has — you select the reference by its group, not by the individual
parameter values:
Note how groupHaving filters at the group level while the sibling referenceContentWithAttributes filter at the
fetch level uses entityHaving to project the matching individual values back into the result. This pairing —
"select by group, project by entity" — is the typical shape of a groupHaving query: the example narrows the
result to MacBooks that have at least one parameterValues reference whose group entity is the ram-memory
parameter, and then for each surviving MacBook fetches only those parameter values whose own code begins with
ram-memory (so the response shows the actual memory size without listing every other parameter the product exposes).
Facet having
argument:string!
the name of the entity reference that will be subject to the filtering
constraints in the second and subsequent arguments
filterConstraint:any*
zero or more filter constraints that identify the facet (reference) that must be present on the entities in
the result set
The
filtering
constraint is typically placed inside the userFilter constraint container and represents
the user's request to drill down the result set by a particular facet. The facetHaving constraint works exactly like
the referenceHaving constraint, but works in conjunction with
the referenceSummary requirement to correctly calculate the
facet statistics and impact predictions. When used outside the userFilter constraint
container, the facetHaving constraint behaves like the referenceHaving constraint.
To demonstrate the cooperation between the facetHaving constraint inside userFilter and the referenceSummary
requirement, let's query for products in category e-readers and request the facet summary for reference brand.
At the same time, let's pretend that the user has already checked the amazon facet:
As you can see, when the facetHaving constraint is detected in the query and the corresponding facet statistics result
is marked as requested, our visualizer chooses to display the facet as checked. The other facet option statistics
reflect the fact that the user has already checked the amazon facet option and the predicted numbers are changed
accordingly:
Facet summary without facet requested
Facet summary after facet requested
Before
After
Because the facet summary JSON is quite long and not very readable, we will only show a simplified version of the facet
summary result in this documentation. As you can see, the selected facet is checked and the predicted numbers have
changed accordingly:
Including children
The
filtering constraint can only be placed within a facetHaving parent constraint and only if the parent constraint refers
to the hierarchical entity. This constraint will automatically propagate all child entities of any entity that matches
the facetHaving constraint to that parent constraint, as if the facetHaving contained the children directly.
Let's illustrate this situation with some real data. Imagine you have a category Laptops with subcategories Netbooks,
Ultrabooks and so on:
Laptops category listing
Products can be related to any of these sub-categories, or directly to the Laptops category (if they don't match any
of the sub-categories). If you generated a facet summary for the category reference, you'd get all the categories with
matching products on the same level. But you may want to visualise the category part of the facet summary as a tree
using the `hierarchy requirement. When the user selects one of
the category options, it should automatically select all subcategories as well, and also change the predicted
reference statistics accordingly.
To achieve this, you can use the includingChildren constraint within the facetHaving constraint. The query is also
restricted to the products of the ASUS manufacturer so that the facet summary is not too long:
Facet summary without including children requested
Facet summary after facet including children requested
Before
After
Because the facet summary JSON is quite long and not very readable, we will only show a simplified version of the facet
summary result in this documentation. As you can see, not only the facet laptops matched by equals function is checked,
but also all of its children. The predicted numbers have changed accordingly:
Including children having
filterConstraint:any+
one or more filter constraints that further narrow down the child entities that will be included in
the facetHaving parent constraint
The
filtering constraint is a specialisation of includingChildren that allows you to restrict
the child entities that are included in the facetHaving parent constraint. This can be useful if you are using
filters in the referenceSummary and your selection
logic needs to match it.
To better understand how the includingChildrenHaving constraint works, let's look at an example (the query is also
restricted to the products of the ASUS manufacturer so that the facet summary is not too long):
Facet summary with standard including children requested
Facet summary with limited facet including children having requested
Before
After
Because the facet summary JSON is quite long and not very readable, we will only show a simplified version of the facet
summary result in this documentation. As you can see, not only the laptops facet matched by the equals function is
checked, but also all of its children whose code attribute contains the string books. The predicted numbers have
changed accordingly:
Including children except
filterConstraint:any+
one or more filter constraints that excludes specific child entities from being included in
the facetHaving parent constraint
The
filtering constraint is a specialisation of includingChildren and exact opposite to [includingChildrenHaving]
that allows you to exclude the matched child entities from being included in the facetHaving parent constraint.
This can be useful if you are using filters in the
referenceSummary and your selection logic needs to
match it.
You can also combine the includingChildrenExcept constraint with the includingChildrenHaving constraint.
In this case, the includingChildrenHaving constraint is evaluated first and the includingChildrenExcept constraint
is applied to the result of the includingChildrenHaving constraint.
To better understand how the includingChildrenExcept constraint works, let's look at an example (the query is also
restricted to the products of the ASUS manufacturer so that the facet summary is not too long):
Facet summary with standard including children requested
Facet summary with limited facet including children except requested
Before
After
Because the facet summary JSON is quite long and not very readable, we will only show a simplified version of the facet
summary result in this documentation. As you can see, not only the laptops facet matched by the equals function is
checked, but also all of its children whose code attribute doesn't contain the string books. The predicted numbers
have changed accordingly:
Histogram having
argument:string!
the name of the entity reference that hosts the histogram to be narrowed
argument:string?
optional histogram name within the reference; may be omitted (or passed as null / empty string) when
the reference hosts exactly one histogram
argument:any?
optional inclusive lower bound (from) of the range; null leaves the range open-ended on the lower side
argument:any?
optional inclusive upper bound (to) of the range; null leaves the range open-ended on the upper side;
at least one of from / to must be non-null
filterConstraint:entityHaving?
optional single entityHaving constraint selecting the group entity for a grouped
histogram slot (for example "the height parameter" within the parameterValues reference); omitted for
non-grouped slots
Group primary key 0 is reserved. Reference histograms use the value 0 as a reserved non-grouped sentinel
across the entire subsystem (in histogramHaving range maps, in the grouped-vs-non-grouped slot key, and in the
ResolvedHistogramHaving carrier). Because evitaDB accepts client-supplied primary keys of any int value
(including negatives), you must not use 0 as a primary key for any entity that may appear as the group
of a reference hosting a histogram. A real group entity with PK 0 will be rejected with an internal error at
query time. Use any non-zero integer (positive or negative) for such entities.
The
constraint narrows a reference histogram to a specific [from, to] range. It is the first-class carrier for
slider-driven range selection on references — for example, a product's parameterValues reference that hosts one
histogram per parameter (height, weight, depth, …). A single histogramHaving identifies one
(referenceName, histogramName, groupSelector, [from, to]) tuple.
Inside the userFilter container, histogramHaving plays a dual role:
it is applied to the filter formula like any other userFilter child — the result set is narrowed by the range;
it is registered as a range carrier so the histogram's own [min, max] baseline cloner peels it out when
computing the histogram — moving one slider does not contract the [min, max] span of sibling sliders (see the
three-group invariant in behavioral filtering).
Outside userFilter, histogramHaving behaves like an equivalent referenceHaving rewrite —
it narrows the result set and does not participate in histogram baseline relaxation.
Expressing independent ranges on the same reference
Two histogramHaving siblings inside one userFilter express independent per-histogram ranges that are combined as
a logical AND — each slider has its own (histogramName, groupSelector, from, to) tuple. The example below narrows
the e-readers category to the products that simultaneously fall into the 200–400 g weight slice and the
6–10 mm thickness slice. Both sliders point at the same parameterValues reference and the same physical
histogram index (intervalParameterValues); the group selector — an entityHaving against the parameter group
entity — is what tells evitaDB which slot (weight vs thickness) each histogramHaving is talking about. The
sibling referenceSummaryOfReferenceWithHistograms in require() then asks the server to compute one full
histogram per parameter group, and because histogramHaving is registered as a range carrier inside userFilter,
each slider's own [min, max] span stays at the catalog-wide baseline rather than collapsing to the user's current
range: