Overview

Optimizely Personalization allows you to discover and take action on your customers' browsing behavior.

In this context, browsing behavior is encoded by event objects, documented below. You will need to become familiar with structure of these event objects in order to write effective behavioral queries.

A behavioral query describes how a single customer's events can be converted into a meaningful value. Each query is specified using a JSON object. The format of these query objects is documented below.

Query Objects

Behavioral queries are specified using JSON objects. The Use Cases section describes how you can evaluate these queries.

Each "step" of query construction creates a new, separate property in the top-level query object.

An empty query object evaluates to the list of all events that have been generated by the current visitor.

1. version

You must include a version number in each of your query objects. This ensures that your query will always be evaluated the same, even if Optimizely introduces a backwards-incompatibile query format in the future.

2. filter

You can filter the results by passing in an array of filters, each comprising a field, comparator, and value. This narrows down the query to those events that match (all) filters.

Note that you can filter by ["age"] even though age is not an actual event field. This is particularly useful if you want to select events that were generated in the last N days.

These comparators are usable on all fields:

  • "eq": Requires the field value to roughly equal the filter's value. For strings, this is case-insensitive, as well as leading- and trailing-whitespace-insensitive.
  • "is": Requires the field value to exactly equal the filter's value.
  • "in": Requires the field value to be contained in the filter's value, which must be an ["array", "of", "acceptable", "values", "such as", 2, "and", true]. For strings, this is case-insensitive, as well as leading- and trailing-whitespace-insensitive.
  • "contains": Requires the field value, which must be an array, to contain the filter's value according to indexOf. For strings, this is case-insensitive.
  • "exists": Requires the field value to be defined; the filter need not specify a value. This is only useful for tags, since top-level fields are defined for every event.

The following string comparators can be used on string fields like type, name, category and also on string tags:

  • "regex": Requires the field value to match the filter's value, which must be either a case-insensitive RegExp "pattern", or a ["pattern", "flags"] array

The following number comparators can be used on numeric fields like time, age and also on numeric tags like revenue. These comparators automatically reject non-numeric field values.

  • "gt": Requires the field value to be greater than the filter's value, which must be a number.
  • "gte": Requires the field value to be greater than or equal to the filter's value, which must be a number.
  • "lt": Requires the field value to be less than the filter's value, which must be a number.
  • "lte": Requires the field value to be less than or equal to the filter's value, which must be a number.
  • "between": Requires the field value to be in the inclusive interval specified by the filter's value, which must be an array of two numbers.

If comparator is omitted, it defaults to "eq".

value can only be omitted when you have specified the "exists" comparator.

3. sort by time

You can sort events by ["time"], either "ascending" or "descending".

4. pick

You can pick the values for a single field out of an array of (potentially filtered and sorted) events.

5. sort by frequency

If field values are being picked out of events, you can sort those values by ["frequency"], either "ascending" or "descending".

This deduplicates the picked values and sorts them based on how frequently each one was found in the filtered events. This will also override any sort that may have been performed on the underlying events.

Unlike conventional field identifiers, ["frequency"] does not correspond to a real event field.

6. reduce

You can reduce a list of values into a single value using an aggregator.

These aggregators are usable on all types of values:

  • "nth": Reduce the list by choosing the nth value and ignoring the rest. "n" is specified separately, and is 0-indexed, so you should specify 0 if you want the first value. This aggregator is only meaningful when values have been sorted.
  • "count": Reduce the list by resolving to the number of values in the list. There is no need to sort or pick when using this aggregator.

The following mathematical aggregators are usable on numeric fields like time, age and also on numeric tags like revenue:

  • "sum": Reduce the list by computing the sum of the numeric values.
  • "avg": Reduce the list by computing the average of the numeric values.
  • "max": Reduce the list by choosing the largest of the numeric values.
  • "min": Reduce the list by choosing the smallest of the numeric values.

Non-numeric values are ignored when evaluating a mathematical aggregator, as if those values didn't exist at all. This ensures, for example, that an "avg" computation is not diluted through zero-filling of undefined values. Note that JavaScript numbers like NaN, +Infinity, and -Infinity are still recognized and can severely affect the result of the aggregation.

Event Objects

Events are one of the core concepts of Optimizely Personalization. In the context of customer behavior, these events are exposed as JavaScript objects.

Fields

Each event object has the following fields:

  • type: 'pageview', 'click', or 'custom'
  • name: A page name, click event name, or custom event name. If you filter by name, you probably want to filter by type as well
  • category: A category name. All events with a given name and type will necessarily have the same category.
  • Various tags: All events from a given page will have those pages' tag values, although additional or overridden tag values may be present on custom events.
  • session_index: identifier for the session in which the event occurred. The sessions are indexed such that the current session is 0, the previous session is 1, and each subsequent session_index is one more than the session which follows it (chronologically).
  • time: The time at which the event occurred (number of milliseconds after January 1, 1970).

Each field can be a number, a boolean, or a string.

Tag fields may also be undefined or some arbitrary JSON value, so be prepared for anything if you're retrieving tag values using the query API.

Field Identifers

When defining a behavioral query, you may need to refer to a particular event field. You can do this using field identifiers.

For top-level fields like time, the identifier is an array containing the name of the field.

  • ["type"]: Identifies the type field.
  • ["name"]: Identifies the name field.
  • ["category"]: Identifies the category field.
  • ["time"]: Identifies the time field.

For tag fields, the identifier is an array containing the string "tags" and then the name of the tag.

  • ["tags", "material"]: Identifies the material tag.
  • ["tags", "color"]: Identifies the color tag.
  • ["tags", "revenue"]: Identifies the special revenue tag. Its value is extracted in Optimizely's analytics backend and used to compute advanced statistics.

When filtering, you can also refer to an event's age. age is not a real event field so it is never actually included in event objects. Compare with time.

  • ["age"]: Identifies the amount of time since an event occurred (number of millseconds before the time at which the query is executed).

Use Cases

JavaScript API

When running Optimizely Personalization, your web page can evaluate a behavioral query on demand using the query API.

Notes:

  • This type of behavioral query can evaluate to a complex value like a list or an event object, in addition to a simple value like a number, boolean, or string.
  • You analyze even more complex behavior by making multiple calls to the JavaScript API.
  • You can also use the JavaScript API to debug behavioral queries that you're planning to use in your Custom Behavioral Attributes.