Filtering on Item Property¶
At times, you may want to have recommendations on items satisfying certain criteria: a price range, the release year of a movie, a minimal popularity, some internal business rule… Filters are provided for this task, enabling your client to dynamically preselect items based on their properties. They are a type of business rules.
Naturally, the richer the items properties, the better the filter, but that’s only the tip of the iceberg since this feature is useful at two different levels:
You can create server-side business rules, such as displaying only new TV-shows in some sections of your app.
You can hand over control to your end user with buttons and switches, so they can configure themselves what they see. Think price range, clothes’ color, category, brand or platform.
Keep in mind that each filter applies to only one item-property; you can then combine multiple filters together, resulting in the intersection of all.
Below, we first present the syntax of filters (the two ways to use them) before moving on to their logic to see what each filter operator does and how to combine them.
Filter Syntax¶
There are two equivalent ways to format a filter:
either using a JSON object
or using a URL-compatible string.
JSON Object Format¶
The JSON object
defining a filter is formed by the following fields:
property_name
: the item-property name on which you want to filterop
: the filter operator (case insensitive). Available operators are defined in Filter Logic belowvalue
: the optional value for the operator.Depending on the operator, this field is either omitted or compulsory. When required, the value type also depends on the item-property type (scalar/string) and on the operator (single scalar/string or list thereof), please see the respective types in the table below.
This field
value
can also be a nestedobject
to define dynamic logic that will be evaluated at runtime. In this case the nested fields are:type
: either"user_property"
or"item_property"
or"timestamp_now"
value
: the name of the property for source property referencingoptions
: type-dependentobject
of options
Dynamic Evaluation
value.type = "user_property"
is used in user-to-* recommendations, to reference the properties of the source user. The inner fieldvalue.value
must be set to the name of the user property of the source user. This doesn’t support anyvalue.options
at the moment.value.type = "item_property"
is used in item-to-* recommendations, to reference the properties of the source item. The inner fieldvalue.value
must be set to the name of the item property of the source item. If the property of the source item cannot be found, it is replaced by the default of the property. This doesn’t support anyvalue.options
at the moment.value.type = "timestamp_now"
is used to test against the unix timestamp at runtime. The inner fieldvalue.value
is not used. This field supports the following options:value.options.rounding_amount
: truncation amount in seconds, larger values means worse precision and better cache rate,value.options.rounding_method
: either"floor"
(default) or"ceil"
URL-Compatible Format¶
The equivalent syntax is also allowed. This is particularly useful to send the filters as URL query parameters.
<PROPERTY_NAME>:<OP>
for operators without value, or
<PROPERTY_NAME>:<OP>:<VALUE>
for operators with a value.
Do remember to use percent-encoding when using reserved characters as values.
Note that nested object values are not available in URL-Compatible format.
Examples¶
price smaller than a number
For instance this filter enforces recommendations of only items with a price strictly less than 10
.
URL-string version: price:lt:10
.
Object version:
{
"property_name": "price",
"op": "lt",
"value": 10
}
tags in a given list
This other filter enforces recommendations of only items with either the tag family
or the tag fiction
.
URL-string version: tags:in:family,fiction
.
Object version:
{
"property_name": "tags",
"op": "in",
"value": ["family", "fiction"]
}
at least one actor
This third filter enforces recommendations of only items which contain at least a value in the property actors
.
URL-string version: actors:NotEmpty
(operators are case-insensitive).
Object version:
{
"property_name": "actors",
"op": "NotEmpty"
}
category in the selected categories of the user
This filter for profile-to-items recommendations enforces recommendations of only items
with category in the list of the user’s selected_categories
.
Here selected_categories
is a repeated user property for which the value will be evaluated at runtime.
URL-string version not available for nested value.
Object version:
{
"property_name": "category",
"op": "in",
"value": {
"type": "user_property",
"value": "selected_categories"
}
}
price higher than the price of the source item
This filter for item-to-items recommendations enforces recommendations of only items with price higher than the price of the source item.
URL-string version not available for nested value.
Object version:
{
"property_name": "price",
"op": "gt",
"value": {
"type": "item_property",
"value": "price"
}
}
availability time greater than the current timestamp
This filter for enforces recommendations of only items with available_from
greater than
the timestamp at the runtime of the query.
The timestamp at runtime will be truncated by at most one hour, to improve caching performances.
URL-string version not available for nested value.
Object version:
{
"property_name": "available_from",
"op": "gt",
"value": {
"type": "timestamp_now",
"options": {
"rounding_amount" : 3600,
"rounding_method": "floor"
}
}
}
Filter Logic¶
You will find below the table of all operators and a detailed description of the filtering logic.
Operators Table¶
The API implements the following operators.
Operator |
Value |
Description |
Quantifier for Repeated Property |
---|---|---|---|
|
scalar |
equal to value |
|
|
scalar |
strictly less than value |
|
|
scalar |
less or equal to value |
|
|
scalar |
strictly greater than value |
|
|
scalar |
greater or equal to value |
|
|
list |
equal to one of the values |
|
|
scalar |
not equal to value (or null) |
|
|
list |
not equal to any of the values (or null) |
|
|
none |
not null |
|
|
string |
full-text search |
|
Note that not all operators are available for all property types. For instance floating point properties suffer from precision issues and therefore cannot be filtered using equality. Please refer to Property Types to find if an operator is available.
Quantifier for Repeated Property¶
For repeated properties, such as a list of many tags
,
most operators follow the exists
set quantifier.
This means that the API will return items where at least one of the repeated values satisfies the operator.
For instance by using the filter tags:eq:family
the API may return items with
{"tags": ["action", "family"]}
or {"tags": ["family"]}
,
but will not return any item with
{"tags": []}
or {"tags": ["action"]}
.
Two operators do not follow this logic and instead implement the forall
set quantifier: neq
and notin
.
For these operators all repeated values must satisfy the operator.
For instance by using the filter tags:notin:family,drama
the API may return items with
{"tags": []}
or {"tags": ["action", "comedy"]}
,
but will not return any item with
{"tags": ["action", "family"]}
or {"tags": ["action", "drama"]}
.
This logic is only relevant for repeated properties because on a set of size 1, exists
and forall
are equivalent.
Full Text Search¶
Experimental feature, behavior is subject to change without notice.
Combining Rules¶
By combining multiple filters you can achieve complex business rules.
Multiple Filters¶
When using multiple filters, the API will return items that satisfy all filters.
For instance using both price:gte:4
and price:lte:10
together
will return only items with a price
between 4
and 10
.
Putting Everything Together¶
By default the operators neq
or notin
also return items with empty sets for this property.
You may want to also exclude these items without the property.
You can achieve this by adding a notempty
filter on the same property.
When using multiple filters on the same repeated property, each filter is considered independently.
Combining all the above logic is a great tool to generate complex business rules,
but it can also produce un-intuitive filtering with repeated integers.
For instance, an item with {"scores": [1, 2, 3, 4]}
satisfies the filters
scores:gt:3 & scores:lt:2
.
Filtering on User Property¶
The same filtering syntax is also implemented to list users who satisfy certain filters.
Although filtering on users is more restricted compared to filtering on items:
* by defaults user properties are not indexed. You need to set the indexed
flag to True
when creating the user property.
* filtering on repeated properties is not implemented
* filtering using ftsearch
operator is not implemented