Crownpeak
  • Product Discovery Developer Guide
  • 🛒Item catalog management
    • What is the Items API?
    • How to work with Items
      • Item Schema
        • Attributes
        • Nested Item Schemas
        • Using the Item Schema API
        • DefaultLocale API
        • Onboarding on/migrating to Fredhopper
        • List of Reserved Attributes
      • Category Tree
        • Using the Category Tree API
        • Onboarding on XO
      • Item Catalog
        • Using the Catalog API
      • Items
        • Using the streaming Items API
        • Using the batch Items API
    • Step by Step guide
      • Step by step guide for Fredhopper customers
    • Feedback
      • Using the Feedback API
    • Authorization to APIs
    • Troubleshooting API errors
  • 🎯XO Recommendations
    • Introduction
    • Using the Recommendations API
    • Setting up the Chrome extension
    • Micro-segmentation
    • XO Legacy APIs
  • 🔎XO Search
    • Introduction
    • Getting started
    • API Reference
      • Search API
      • Autocomplete API (Beta)
      • Product Suggest API
    • API Parameters
      • Search
      • Pagination
      • Faceting
      • Sorting
      • Grouping
      • Filtering
      • Disable features
      • Response mask
      • Context
    • Configuration limitation
  • 🧪A/B testing
    • Fredhopper A/B testing
      • Integration steps for a non-caching solution
      • Integration steps for a caching solution
        • Java SDK Integration
          • Setup
          • Retrieve running A/B tests - Java SDK
          • Filter and request variant - Java SDK
          • Extending the SDK
        • Manual A/B tests integration
          • Retrieve running A/B tests
          • Filter out irrelevant A/B tests
          • Assign variants to user
          • Request variant for page
        • Limitations and Best Practices
  • 📚Resources
    • Glossary
    • Best Practices
      • Tracker Best Practices
      • Items API Best Practices
      • Fredhopper Data Configuration Best Practices
      • Fredhopper Query Response Best Practices
      • Fredhopper Merchandising Studio Best Practices
    • Privacy Notice
  • Archived Pages
    • FHR Tracking plan
    • XO Tracking plan
    • The Tracking API and JS Library
      • What to Track
        • Generic Actions
          • View
          • Click
          • Add to Cart
          • Remove from Cart
          • Purchase
        • Custom Actions
      • Initializing the JavaScript Library
      • REST API Technical Documentation
Powered by GitBook
On this page
  • Example response
  • Filtering
  1. A/B testing
  2. Fredhopper A/B testing
  3. Integration steps for a caching solution
  4. Manual A/B tests integration

Filter out irrelevant A/B tests

There can be many A/B tests running on the platform, but only some that are relevant for a given page. Without filtering, we would need to have variant combinations for all of the running A/B tests for that page, resulting in unnecessary requests that need to be cached, as even though an irrelevant A/B test would not trigger on a page, you would still end up adding the A/B test to the request, thus making it a different request. To avoid this, we want to filter out the irrelevant A/B tests.

Example response

Consider the example response below:

[
    {
      "id": "318ccefa-bb47-4589-945d-ccc0c4f32280",
      "variations":[
         {
            "id": "06c26226-25bc-4054-b622-62fcbe4db3fd",
            "weight":50
         },
         {
            "id": "4f4bdc48-a586-4670-985b-b8de7d028773",
            "weight":50
         },
      ],
      "filters": {
         "fh_location": ["//catalog01/en_GB/color>{black}.*"],
      }
    }
]

In the response we have a single A/B test with the following properties:

  • 318ccefa-bb47-4589-945d-ccc0c4f32280 as the A/B test id

  • Two variants or variations each with a weigh distribution of 50% and their corresponding ids

    • 06c26226-25bc-4054-b622-62fcbe4db3fd for the first one

    • 4f4bdc48-a586-4670-985b-b8de7d028773 for the second one

  • A single filter in the filters object which states that the A/B test is active on pages whose fh_location parameter matches the RegEx //catalog01/en_GB/color>{black}.* which translates to all navigation pages within the catalog01 universe, with locale en_GB, which start with a facet selection of color: black.

The filters are configured when the A/B test is created. Most of the time, the only available key would be fh_location, but there might me multiple RegEx patterns to match. We will work with the fh_location parameter in this example, but the process is completely the same for any other parameter.

Filtering

In order to filter out irrelevant A/B tests for a given page all we need to do is some RegEx pattern matching. If the page you want to request matches ALL of the patterns for ALL of the properties in filters, then you have a match and the A/B test should be used. If you have query parameters that there are no filters present for, you can assume a match. If on the contrary there are filters for a query param which you don't have in your query for the page, you can assume a mismatch.

Let's look at the fh_location example in the response above. Consider the following pages:

  • A page with fh_location: "//catalog01/fr_FR/color>{black}" will not match, because the locale in the path doesn't match the one we have in the filter.

  • A page with fh_location: "//catalog01/en_GB/spotlight>{new}/color>{black}" will not match, because the color facet is not the first one selected while navigating.

  • A page with fh_location: "//catalog01/en_GB/color>{black}/spotlight>{new}" will match, because the color facet the first one selected while navigating, and the color is black.

To confirm whether a value is a match, all you need to do is perform a RegEx match in your language of choice, which in Java is:

boolean matches = propertyValue.matches(pattern);
let match = propertyValue.match(pattern);
$match = preg_match($pattern, $propertyValue)

As mentioned before, this needs to be done for all patterns of a property, for all properties available in filters:

boolean matchAbTestWithParams(RunningAbTest runningAbTest, Map<String, String> params) { // params represents the query params in the request which would be made to FAS(without new the fh_abtests parameter)
    for(Map.Entry<String, List<String>> entry: runningAbTest.getFilters().entrySet()) { // we run through all of the filters available for a given A/B test
        if(params.containsKey(entry.getKey())) {
            for(String pattern: entry.getValue()) { // for all patterns for the given key, we check if our parameter value matches the patterns
                if(!params.get(entry.getKey()).matches(pattern)) return false; // if any pattern doesn't match we ignore the test
            }
        } else { // if we do not have the required key in our params, then this test definitely doesn't match so we ignore it
            return false;
        }
    }

    return true; // if all conditions are met, we use the A/B test
}
const matchAbTestWithParams = (runningAbTest, params) => { // params represents the query params in the request which would be made to FAS(without new the fh_abtests parameter)
    for(const [key, patterns] of Object.entries(runningAbTest.filters)) { // we run through all of the filters available for a given A/B test
        if(params[key]) {
            for(let pattern of patterns) { // for all patterns for the given key, we check if our parameter value matches the patterns
                if(!(params[key].match(pattern))) return false; // if any pattern doesn't match we ignore the test
            }
        } else { // if we do not have the required key in our params, then this test definitely doesn't match so we ignore it
            return false;
        }
    }
    return true; // if all conditions are met, we use the A/B test
}
function matchAbTestWithParams($runningAbTest, $params) { // params represents the query params in the request which would be made to FAS(without new the fh_abtests parameter)
    foreach($runningAbTest['filters'] as $key => $patterns) { // we run through all of the filters available for a given A/B test
        if($params[$key]) {
            foreach($patterns as $pattern) { // for all patterns for the given key, we check if our parameter value matches the patterns
                if(!preg_match($pattern, $params[$key])) return false; // if any pattern doesn't match we ignore the test
            }
        } else { // if we do not have the required key in our params, then this test definitely doesn't match so we ignore it
            return false;
        }
    }
    return true; // if all conditions are met, we use the A/B test
}

Everything mentioned in this section is also covered via the SDK.

Once you have the irrelevant A/B tests filtered out you can move on to assigning variants to the user.

PreviousRetrieve running A/B testsNextAssign variants to user

Last updated 3 years ago

🧪
Assign variants to user