Discount Predicates

Certain resources have a predicate or cartPredicate field. In particular, Product Discounts, Cart Discounts, and Shipping Method have predicate fields. This field expects a conditional statement known as a predicate. When a predicate evaluates as true, the API applies the discount or selects a shipping method.

Predicates consist of field identifiers and operators. For more information on the identifiers that you can use to create predicates, see Discount Predicate Identifiers.

You cannot use the syntax described here to construct API queries using the where field. General-purpose queries use a different syntax. For more information, see Query Predicates.

Predicate syntax

Predicates consist of three elements:

For example, take the following ProductDiscount predicate:

sku = "AB-123"
  • The predicate field identifier for the Product Variant is sku.
  • The operator is =.
  • The value is "AB-123".

Operators always evaluate contextually aware values before comparing or evaluating the predicate. The API ensures that the values of the field identifiers are compatible with the values provided. For example, Strings will only evaluate against Strings. Constructing a predicate that compares different data types – String and Number, for example – returns a 400 Bad Request. One exception to this rule is comparison operators, however.

Operators

Equality operators

Equality operators compare a field identifier with a value.

OperatorDescription
=Checks if the field identifier's value equals the comparison value.
!= or <>Checks if the field identifier's value is not equal to the comparison value.

Example:

product.key = "holidayTShirt"
  • The predicate field identifier is product.key.
  • The operator is =.
  • The value is "holidayTShirt".

Example:

custom.season = ("spring2019", "summer2019")
  • The field identifier is custom.season.
  • The operator is =.
  • The values to compare are "spring2019" and "summer2019".

When using the = when comparing collections, = only returns true for exact matches: both "spring2019" and "summer2019" must be present in custom.season, and no other values. In most cases, we recommend using a containment operator to compare collections.

Comparison operators

Comparison operators compare the value of two numbers or number-like fields. You can use comparison operators on the following predicate identifiers:

You can only use comparison operators when comparing a single value to a single value.

OperatorDescription
>Checks if the field identifier's value is numerically greater than the comparison value.
>=Checks if the field identifier's value is numerically greater than or equal to the comparison value.
<Checks if the field identifier's value is numerically less than the comparison value.
<=Checks if the field identifier's value is numerically less than or equal to the comparison value.

Containment operators

Containment operators check if a collection contains or does not contain one or more specified values. You can only use containment operators on fields holding a collection of values, like arrays and sets:

OperatorDescription
containsChecks if a field identifier contains a value.
contains anyChecks if a field identifier contains any of the value(s) in a set.
contains allChecks if a field identifier contains all of the value(s) in a set.
inChecks if a field identifier's value(s) is contained in an array.
not inChecks if a field identifier's value(s) is not contained in an array.

Example:

attributes.season contains "spring2019"
  • The field identifier is attributes.season.
  • The operator is contains.
  • The values to check are "spring2019".

This example evaluates as true if spring2019 is contained in a product's season attribute. For this request to succeed, season must be a Set type.

attributes.season contains any ("spring2019", "summer2019")
  • The field identifier is attributes.season.
  • The operator is contains any.
  • The values to check are "spring2019" and "summer2019".

This example evaluates as true if either spring2019 or summer2019 are contained in a product's season attribute. For this request to succeed, season must be a Set type.

attributes.season contains all ("spring2019", "summer2019")
  • The field identifier is attributes.season.
  • The operator is contains all.
  • The values to check are "spring2019" and "summer2019".

This example evaluates as true if both spring2019 and summer2019 are contained in a product's season attribute. If only one is present, this example evaluates as false. For this request to succeed, season must be a Set type.

Example:

attributes.size in ("xxl", "xl")
  • The field identifier is attributes.size.
  • The operator is in.
  • The values to compare are "xxl" and "xl".

This example evaluates as true if either xxl or xl are contained in a product's size enum attribute.

Defined and empty operators

Defined and empty operators check whether a field or collection has a value. Defined and empty operators are only used on optional fields on a resource.

You can use the is defined and is not defined operators with any single value field.

You can only use the is empty and is not empty fields with collections:

OperatorDescription
is definedChecks if a field identifier exists on a resource and contains a value.
is not definedChecks if a field identifier does not exist on a resource.
is emptyChecks if a collection does not contain values.
is not emptyChecks if a collection contains values. Does not check on the content of the values themselves.

Examples:

channel.id is not defined
  • The field identifier is channel.id.
  • The operator is is not defined.
  • No value is explicitly provided in this predicate, the value, in this case, is implicitly true.

In this example, defining a Product's channel is not required when creating a new product. This statement evaluates as true if no product channel is set.

country is defined
  • The field identifier is country.
  • The operator is is defined.
  • No value is explicitly provided in this predicate, the value, in this case, is implicitly true.

In this example, once again, a Cart does not need to have a country defined. This statement evaluates as true if a country is in fact set.

attributes.season is empty
  • The field identifier is attributes.season.
  • The operator is is empty.
  • No value is explicitly provided in this predicate, the value, in this case, is implicitly true.

This example evaluates as true if a Product Type has an season attribute but it does not have a default value.

Combining and nesting operators

You can combine operators to create more complex or nested conditional predicates.

SyntaxDescription
orA logical disjunction: if the first condition or the second condition is true...
andA logical conjunction: if the first condition and the second condition are true...
notA logical negation: if the condition is not true..
( )Nests predicate conditions.

Examples:

custom.bookingStart = "2016-11-24" and custom.bookingEnd = "2016-12-04"
  • The first field identifier is custom.bookingStart.
  • The first operator is =.
  • The first value is "2016-11-24".
  • The and keyword combines the two statements so that both must be true.
  • The second field identifier is custom.bookingEnd.
  • The second operator is =.
  • The second value is "2016-12-04".

You can also nest parentheses:

not(product.key = "holidayTShirt" and(product.price = "10.00 EUR" or product.price = "20.00 EUR"))

This example only evaluates true if the product.key is not "holidayTShirt", and it does not have a price of 10 or 20 euros.

Using the not operator

The not operator, when used in conjunction with any other operator, negates the statement inside of parentheses. This is most useful when using the contains operators, to check if an item is not inside a given collection.

Example:

not(product.key = "holidayTShirt" or product.id = "456")

The or keyword ensures that if only one of the equality statements needs to evaluate as true. If product.id equals 456, or the product.key is "holidayTShirt" outer not statement will evaluate as false.