Overview
Pre-filters is a feature built into GroupBy’s search engine that allows you, at query time, to limit the search space to a subset of records in a collection.
Creating such subsets allow you to form custom catalogs for your customers. Customized subsets of the whole collection could be unique per customer.
It provides you the total control over determining visibility of products based on shopper information and product attributes by using logical operators and boolean functions (AND, OR) that can be crafted and changed from query to query for all your customers.
Query Logic
A query logic is the main part of the language that allows an attribute to be constrained by a particular value, such as person.firstName = "John"
or a set of values, such as contractId in ["a1", "b2", "c3"]
. A query logic follows the grammar:
<fieldname> <operator> <value>
Field Name
The field name represents the JSON path
dot
notation to the attribute
on the record. For example, person.firstName
. This field name has two parts:
- Field =
firstName
- Nested object =
person
Each part of a field name must conform to the following rules:
- Must only contain alphabetic characters in lower and upper case, digits, underscores or hyphens.
- Must not begin with a hyphen or a digit.
Good Examples:
contractId
contract-id
contract_id
person.firstName
owner.first-name
_metadata.tags
Sales2020_Rating
Bad Examples:
.firstName //Not a valid JSON path
lastName. //Not a valid JSON path
category.33 //Second part starts with a digit
-Internal.promo //First part starts with a hyphen
hastag# //Contains special character
Every field (attribute) in a pre-filter expression needs to be defined as refinable
in the upload config file. If the field is not refinable, search result will return an error.
-
You can use nested fields in pre-filters expression only if they are not set to child-record in the upload config file.
-
If an attribute specified in a pre-filter expression does not exist on any record, search results will be empty as no records match that expression.
List of Operators
Here is a list of operators we can support:
Operator | Description | Boolean | Float | Integer | String | List |
---|---|---|---|---|---|---|
= | Equals | Yes | Yes | Yes | Yes | No |
!= / not = | Not equals | Yes | Yes | Yes | Yes | No |
> | Greater than | No | Yes | Yes | No | No |
>= | Greater than or equal to | No | Yes | Yes | No | No |
< | Less than | No | Yes | Yes | No | No |
<= | Less than or equal to | No | Yes | Yes | No | No |
in | In | No | Yes | Yes | Yes | Yes |
!in / not in | Not in | No | Yes | Yes | Yes | Yes |
contains | Contains | No | Yes | Yes | Yes | No |
!contains / not contains | Not contains | No | Yes | Yes | Yes | No |
Values
Values are static literals and can be of different types as follows:
Boolean: A boolean value is either true or false, case-insensitively. True
, true
, false
, and fALsE
are all valid boolean values.
Integer: A whole number. Any leading zeros will be ignored, so 0053 and 53 will have the same effect.
Decimal: A decimal number, also known as a float, contains a whole part and a fractional part, such as 3.14.
String: A string literal is surrounded by double quotes (") and can contain any character except for double quotes. Escaping double quotes is not currently supported; for example, "2.5\" screw"
is not a valid string literal. Any space in a string value will not be ignored; in the example (ONLINE_FLAG=\"1 \")
, the value will be interpreted as 1, followed by space.
Examples of valid string literals include:
"Cars!"
"12 Cans"
"Juice"
List: A list is an ordered set of items surrounded by square brackets ([]) and separated by commas (,). Whitespace is ignored, and items can be integers, decimal numbers, or string literals. However, all items in a list must have the same type.
Good Examples:
[1,2,3]
[1.5, 3.14, 4.7801]
["Volvo", "BMW", "Ford"]
Bad Example:
[12, "price"]
Chaining Query Logic
Query Logic can be chained together using and
or or
connectives (that are case insensitive) to build more sophisticated expressions. For example:
metadata.tags contains "healthy" OR calories <= 400 AND containsNuts = false
By default, the leftmost connective takes precedence. Therefore, a record that has the string "healthy"
in the array attribute metadata.tags
still needs to have the attribute containsNuts
set to false
to match the expression above.
Parenthesis
Parenthesis ( )
can be used to limit the scope of chained query logic, effectively controlling the precedence of connectives in an expression. Therefore, the above expression can be changed to the following to ensure all “healthy” records are eligible regardless of their other attributes:
metadata.tags contains "healthy" OR (calories <= 400 AND containsNuts = false)
All opening parentheses must be closed and they may be nested as required. For example:
(
(
contractId in [12, 56, 34]
or
hazardous=false
)
and
visibility='special'
)
or
public=true
Order of Processing
The conditions dictated by a pre-filter, if met, narrows down the records (i.e., products) in a collection. These records are then included in the search space.
Any search refinements or queries will be applied after this subset of records is created.
In a nutshell, expression defined by pre-filters are applied before any other search functionality.
Use Case
Custom Catalogs
Consider a scenario where you want the ability to restrict a shoppers’ visibility into products returned by the search engine based off some condition.
It is rather complex to create and manage multiple business rules for multiple shoppers. Creating separate collections for each such business rule may not be a scalable solution either.
The pre-filters feature can be leveraged for this.
For example, if you want to restrict the visibility of Product Set A
only to Customer Set B
, you may leverage some information specific to Customer Set B to do so. For instance, their product contracts.
You can present that information as a boolean statement of contract related attributes in your query, in order to limit the results to those that satisfy the logical statement.
Implementing Pre-Filters
Pre-filters are specificed in the request body while sending a request to the Search API.
As a user of the API, you can leverage the Search API to restrict all proceeding queries by an end-user of a Search implementation specifically to products that have:
The Brand equals Adidas and Gender is either Men or Women, and Price is less than the numeric value of 60 or Color equals to Green and Category ID contains 220.
curl -d '{
"query": "country",
"clientKey": "Your client key",
"pre-filter":"BRAND = \"Adidas\" and (gender = \"Men\" or gender = \"Women\" ) AND variants.stores.price < 60 or (variants.color = \"Green\") and (categoryId CONTAINS \"220\")"
}' "https://yourCustomerID.groupbycloud.com/api/v1/search"