Skip to main content

Orchestrating Multiple Personalization Strategies Simultaneously

Splitting Traffic with Multiple Data Sources

In this recipe, we are building an blog page that includes the blog content along with a set of related blogs that the reader should be interested in reading next. We have three separate sources that can provide a list of recommended related blogs:

  • Blogs belonging to the same category in our CMS
  • Blogs that have been manually linked to this blog in our CMS
  • Blogs that Algolia Recommend has determined using its Related Content model

We're not sure which set of recommended blogs will get the most clicks, so we're going to split the traffic between the three sources using Conscia's multivariant testing capabilities.

This same recipe can be used for product or service recommendations.

Overall Orchestration Flow

We will be using Contentful as our blog post data source, and Algolia Recommend as one source of our related blogs. When the blog page is loaded, it will call Conscia's Experience API with the article id. Conscia will return the full blog content along with the information required to generate tiles for the related posts from one of three sources.

The Orchestration consists of Connections to Contentul and to Algolia Recommend, as well as the necessary Selector and Mapper Components to get both the blog entry data as well as the information required for the related content links. Selector Components retrieve data from a Connection's endpoint, and Mapper Components map, transform, and merge those responses.

The multivariant testing is set in an Experience Rule on a Source Picker Component. The Model component will then provide the response from the appropriate Mapper Component source based on the Picker.

In order for your analytics engine of choice to get the data required to analyze the multivariant testing results, create an Orchestration Template with two Components:

  • The Mapper Component that provides the full page content.
  • The Picker Component that tells you which related content source has been selected.

Mapping Out DX Engine Elements

Recommendations Visualizer

  • Context: The articleId of the main blog entry to load is passed in through Context.
  • Contentful - Get Fashion Blog and Mapper - Fashion Blog: Selector and Mapper Components for the Contentful blog entry.
  • Contentful - Get Fashion Blog - By Category and DTS Mapper - Fashion Blog - Contentful By Category: Selector and Mapper Components for the Contentful blogs from the same category.
  • Contentful - Get Fashion Blog - Related Article Ids and Mapper - Fashion Blog - Contentful Related: Selector and Mapper Components for the Contentful blogs linked from the main blog entry.
  • Algolia Recommend - Fashion Blogs - Related Content and Mapper - Fashion Blog - Algolia Recommend: Selector and Mapper Components for the Algolia Recommend selected blogs
  • Article Recommendations Source: Picker Component for the user to determine which related blog source to use and/or to set up multivariant testing via Experience Rules.
  • Model - Related Articles (by source): Model Component to pull the correct related blog entries based on the Picker's selection.
  • Mapper - Fashion Blog - Full Page Content: Mapper Component to pull together the blog entry itself along with the related article data, everything required to render the full page content.

The Experience API request will look something like this:

POST {{engineUrl}}/experience/components/_query
X-Customer-Code: {{customerCode}}
Authorization: Bearer {{dxEngineToken}}

{
"componentCodes": ["mapper-fashionblog-fullpagecontent"],
"context": {
"articleId": "90"
}
}

The Experience API response will look something like this:

"blog": {
"title": "London Fashion Week Spring/Summer 2022: The Shows – In Pictures",
"author": "Helen Seamons, Jo Jones and Peter Bevan",
"content": "The first digital-only London Fashion Week brought together a hugely diverse series of shows and subject matter from Syrias Six Day War to Cecil Beatons Bright Young Things. From Ahluwalia to Qasimi …",
"imageUrl": ...,
"published": "2021-06-16T11:18:29Z"
},
"includes": {
"related": [
{
"title": "Elegance Redefined: Female Fashion Trends for 2023",
"articleId": "192",
"imageUrl": ...
},
{
"title": "Dapper and Suave: A Guide to Men's Fashion Suits",
"articleId": "54",
"imageUrl": ...
},
{
"title": "The Digital Runway: How Technology is Transforming Fashion Shows",
"articleId": "85",
"imageUrl": ...
}
]
}

DX Engine Configuration Details

This recipe builds on the Related Articles with Algolia Recommend recipe. You can find instructions for creating the Contentful and Algolia Connections there.

Create a Component to retrieve blog content from Contentful

  • Navigate to the Experience Components page (Manage Experiences --> Components)
  • Click the + Add Component button.
  • Enter the following and click Submit.
FieldValue
Component Codecontentful-get-fashionblog
Component NameContentful - Get Fashion Blog
No RulesChecked
Component TypeConscia - Universal API Connector

The DX Engine will create and prepare the Component for further configuration. You should see the new component appear in the Component listing.

  • Click Edit.
  • Enter the following and click Submit.
FieldForm TabValue
ConnectionMainContentful Connection
Webservice PathMainGet value from: JS Expression
/entries/${contextField('articleId')}
MethodMainGET

Create a Component to transform blog content from Contentful

  • Navigate to the Experience Components page (Manage Experiences --> Components)
  • Click the + Add Component button.
  • Enter the following and click Submit.
FieldValue
Component Codemapper-fashionblog
Component NameMapper - Fashion Blog
No RulesChecked
Component TypeConscia - Object Mapper

The DX Engine will create and prepare the Component for further configuration. You should see the new component appear in the Component listing.

  • Click Edit.
  • Create an Object Map as follows and click Submit.
FieldValue
Source DataGet value from: Component Response
Contentful - Get Fashion Blog
Expression TypeJMESPath
Schematitle = fields.title
author = fields.author
content = fields.content
imageUrl = fields.urlToImage
published = fields.publishedAt
  • Navigate to the Experience Components page (Manage Experiences --> Components)
  • Click the + Add Component button.
  • Enter the following and click Submit.
FieldValue
Component Codecontentful-get-fashionblog-bycategory
Component NameContentful - Get Fashion Blog - By Category
No RulesChecked
Component TypeConscia - Universal API Connector

The DX Engine will create and prepare the Component for further configuration. You should see the new component appear in the Component listing.

  • Click Edit.
  • Enter the following and click Submit.
FieldForm TabValue
ConnectionMainContentful Connection
Webservice PathMainGet value from: Literal
/entries
MethodMainGET
Query ParametersMainParameter: content-type
Value (Literal): fashion-blog
Query ParametersMainParameter: fields.category
Value (JS Expression): _.head(componentResponse('contentful-get-fashionblog-universal').fields.category)

In the fields.category query parameter, we're simply pulling the first category assigned to the main blog article.

  • Navigate to the Experience Components page (Manage Experiences --> Components)
  • Click the + Add Component button.
  • Enter the following and click Submit.
FieldValue
Component Codedtsmapper-fashionblog-related-contentful-category
Component NameMapper - Fashion Blog - Contentful By Category
No RulesChecked
Component TypeConscia - Data Transformation Script

The DX Engine will create and prepare the Component for further configuration. You should see the new component appear in the Component listing.

  • Click Edit.
  • Create an Object Map as follows and click Submit.
FieldValue
Data to modifyGet value from: JS Expression
_.assign({}, {"articles" : componentResponse('contentful-get-fashionblog-bycategory').items, "idToRemove" : contextField('articleId')})
Script
let relatedArticles = data.articles.map((item) => ({
title: item.fields.title,
articleId: item.sys.id,
imageUrl: item.fields.urlToImage,
}));

relatedArticles.forEach( (item, index, object) => {
if (item.articleId === data.idToRemove) {
object.splice(index, 1);
}
});

const related = {"related": relatedArticles};
related;
  • Navigate to the Experience Components page (Manage Experiences --> Components)
  • Click the + Add Component button.
  • Enter the following and click Submit.
FieldValue
Component Codecontentful-get-fashionblog-related-articleids
Component NameContentful - Get Fashion Blog - Related Article Ids
No RulesChecked
Component TypeConscia - Universal API Connector

The DX Engine will create and prepare the Component for further configuration. You should see the new component appear in the Component listing.

  • Click Edit.
  • Enter the following and click Submit.
FieldForm TabValue
ConnectionMainContentful Connection
Webservice PathMainGet value from: JS Expression
/entries/${contextField('articleId')}
MethodMainGET
Response TransformMainresponse.fields.relatedArticles.map(e => _.identity({id: e.sys.id}))
Property NameSub ComponentsrelatedArticleDetails
Component CodeSub Componentscontentfulgetfashionblogrelated
Context Field for Sub ComponentSub ComponentsContext Field: relatedArticleId
Expression: response.id

The Response Transform is required to provide an array to the Sub Component in order for it to iterate over the articleIds.

This Component is used as a Sub Component in the above configuration. For each articleId passed to it from the base Component's response array, it will retrieve the blog details required to generate a tile for related content. The entire set will be returned in a single response in a property called relatedArticleDetails embedded in the base Component's response.

  • Navigate to the Experience Components page (Manage Experiences --> Components)
  • Click the + Add Component button.
  • Enter the following and click Submit.
FieldValue
Component Codecontentfulgetfashionblogrelated
Component NameContentful - Get Fashion Blog - Related Article Detail
No RulesChecked
Component TypeConscia - Universal API Connector

The DX Engine will create and prepare the Component for further configuration. You should see the new component appear in the Component listing.

  • Click Edit.
  • Enter the following and click Submit.
FieldForm TabValue
ConnectionMainContentful Connection
Webservice PathMainGet value from: JS Expression
/entries/${contextField('relatedArticleId')}
MethodMainGET
Response TransformMain_.assign({'title': response.fields.title, 'articleId': response.sys.id, 'imageUrl': response.fields.urlToImage})

The Response Transform is used in lieu of a separate mapper Component to map and transform just the required properties.

  • Navigate to the Experience Components page (Manage Experiences --> Components)
  • Click the + Add Component button.
  • Enter the following and click Submit.
FieldValue
Component Codemapper-fashionblog-related-contentful
Component NameMapper - Fashion Blog - Contentful Related
No RulesChecked
Component TypeConscia - Object Mapper

The DX Engine will create and prepare the Component for further configuration. You should see the new component appear in the Component listing.

  • Click Edit.
  • Create an Object Map as follows and click Submit.
FieldValue
Source DataGet value from: Component Response
Contentful - Get Fashion Blog - Related Article Ids
Expression TypeJMESPath
Source Array Property Path$
Target Property Path for modified arrayrelated
Schematitle = relatedArticleDetails.contentfulgetfashionblogrelated.response.title
articleId = relatedArticleDetails.contentfulgetfashionblogrelated.response.articleId
imageUrl = relatedArticleDetails.contentfulgetfashionblogrelated.response.imageUrl
Response Transform_.assign({}, {"related" : response})
  • Navigate to the Experience Components page (Manage Experiences --> Components)
  • Click the + Add Component button.
  • Enter the following and click Submit:
FieldValue
Component Codealgolia-recommend-fashionblogs-related
Component NameAlgolia Recommend - Fashion Blog - Related Content
No RulesChecked
Component TypeConscia - Universal API Connector

The DX Engine will create and prepare the Component for further configuration. You should see the new component appear in the Component listing.

  • Click Edit.
  • Enter the following and click Submit.
FieldForm TabValue
ConnectionMainAlgolia Recommend Connection
Webservice PathMainGet value from: Literal
/1/indexes/*/recommendations
MethodMainPOST
BodyMainGet value from: JS Expression
{
"requests": [
{
"indexName": "{index to target}",
"model": "related-products",
"threshold": 45,
"maxRecommendations": 3,
"objectID": "${contextField('articleId')}"
}
]
}
  • Navigate to the Experience Components page (Manage Experiences --> Components)
  • Click the + Add Component button.
  • Enter the following and click Submit.
FieldValue
Component Codemapper-fashionblog-related-algolia
Component NameMapper - Fashion Blog - Algolia Recommend
No RulesChecked
Component TypeConscia - Object Mapper

The DX Engine will create and prepare the Component for further configuration. You should see the new component appear in the Component listing.

  • Click Edit.
  • Create an Object Map as follows and click Submit.
FieldValue
Source DataGet value from: Component Response
Algolia Recommend - Fashion Blog - Related Content
Expression TypeJMESPath
Source Array Property Pathresults[0].hits
Target Property Path for modified arrayrelated
Schematitle = title
articleId = article_id
imageUrl = urlToImage
  • Navigate to the Experience Components page (Manage Experiences --> Components)
  • Click the + Add Component button.
  • Enter the following and click Submit.
FieldValue
Component Coderelated-content-source
Component NameFashion Blog - Related Content Source
No RulesChecked
Component TypeConscia - Metadata
  • Navigate to the Omnichannel Experience Rules page (Manage Experiences --> Experience).
  • Navigate to your Fashion Blog - Related Content Source Component under All Components.
  • Click the + Add Experience Rule button.
  • Enter the following and click Submit.
FieldForm TabValue
Rule IDMainsplit-traffic
Rule NameMainSplit Traffic
PriorityMain1
Is DefaultMainChecked
Enable A/B TestMainChecked
A/B Test Configuration: StickinessMainYour choice: visitor / session
FieldForm TabValue
ActiveExperienceChecked
DatesExperienceOptional
  • Under Target Experience, add three Weighted Configurations then click Submit.
FieldValue
Control GroupChecked
Relative Weight33
Variant IdentifierBy Category
InstructionsKey: recommendationsType
Value: Articles by Category
FieldValue
Control GroupNot Checked
Relative Weight33
Variant IdentifierRelated
InstructionsKey: recommendationsType
Value: Related Articles from Contentful
FieldValue
Control GroupNot Checked
Relative Weight34
Variant IdentifierAlgolia Recommend
InstructionsKey: recommendationsType
Value: Algolia Recommendations

In this recipe weight is distributed equally across all three options.

  • Navigate to the Experience Components page (Manage Experiences --> Components)
  • Click the + Add Component button.
  • Enter the following and click Submit.
FieldValue
Component Codemodel-related-content
Component NameModel - Fashion Blog - Related Content (by source)
No RulesChecked
Component TypeConscia - Metadata

The DX Engine will create and prepare the Component for further configuration. You should see the new component appear in the Component listing.

  • Click Edit.
  • Add the Response Transform expression as follows and click Submit.
FieldValue
Response Transform
componentResponse('recommendations-source').recommendationsType[0] === 'Algolia Recommendations' ? componentResponse('mapper-fashionblog-related-algolia') : componentResponse('recommendations-source').recommendationsType[0] === 'Related Articles from Contentful' ? componentResponse('mapper-fashionblog-related-contentful') : componentResponse('recommendations-source').recommendationsType[0] === 'Articles by Category' ? componentResponse('dtsmapper-fashionblog-related-contentful-category') : {}
  • Navigate to the Experience Components page (Manage Experiences --> Components)
  • Click the + Add Component button.
  • Enter the following and click Submit:
FieldValue
Component Codemapper-fashionblog-fullpagecontent
Component NameMapper - Fashion Blog - Full Page Content
No RulesChecked
Component TypeConscia - Property Mapper

The DX Engine will create and prepare the Component for further configuration. You should see the new component appear in the Component listing.

  • Click Edit.
  • Create two Property Maps as follows and click Submit.
FieldValue
Source DataGet value from: Component Response
Mapper - Fashion Blog
Expression TypeJavascript
MappingsTarget property: blog
Source expression: data
FieldValue
Source DataGet value from: Component Response
Model - Fashion Blog - Related Content (by source)
Expression Typejavascript
MappingsTarget property: includes
Source expression: data

References