content_intersect

Given two JSON arrays of content items, returns only those items which exist in both arrays.

Copy
array content_intersect( array content1, array content2 )

The source arrays can be:

  • content objects from a Horizon content feed.
  • content objects from a custom content feed.
  • horizon_select item recommendations for the user.
  • Predictions item predictions for the user.

For example, you could use this function to return items that are in both your custom Popular Content feed and in the horizon_select array of user-specific item recommendations. This function is also the exclusive method for surfacing Predictions item predictions in your templates. If you have implemented Predictions, the Zephyr function item_predictions returns an array of item IDs representing the items that the user is most likely to purchase. To return content objects matching those item IDs, use content_intersect on that array of IDs in conjunction with a Horizon content feed, a custom content feed, or the user’s horizon_select recommendations.

Examples

Return an array of items that are in your custom feed* and also match horizon_select recommendations for the user
content_intersect(horizon_select(), content)

*The “content” array uses whichever feed has been selected by your template, whether a Horizon content feed or a custom content feed. Return an array of predictions matching the template’s current feed

content_intersect(item_predictions(50), content)
 
Return an array of predictions matching horizon_select recommendations for the user
content_intersect(item_predictions(50), horizon_select())

Display the Intersection of User-Interested and Trending Content

Use Case: Using collaborative filtering, you wish to find all items that are “trending” in your Content Library, but you only want to display the top three of those items to users based on user interest data from your Content Library. Used in conjunction with the personalize() function.

Zephyr:

{**Find 100 items a user is interested in and 100 items that are popular**}
{interestContent = personalize({"algorithm":"interest","size":100})}
{popularContent = personalize({"algorithm":"popular", "size":100})}
{**Desired number of items**}
{recNum = 10}
{**FInd the intersect of the popular and interested items**}
{personalizedContent = content_intersect(interestContent,popularContent)}
{**Create a backup length if there are less than the number of desired item**}
{backupLength = recNum - length(personalizedContent)}
{**If the length of backup items is greater than 0, find unique content in the interestContent object to backfill the remaining items**}
{if backupLength > 0}
{usedcontent = []}
{personalizedContent = filter(personalizedContent, lambda c: (contains(usedcontent, c.url) ? false : push("usedcontent", c.url) || true))}
{backupContent = filter(interestContent, lambda c: (contains(usedcontent, c.url) ? false : push("usedcontent", c.url) || true))}
{backupContent = personalize({
"algorithm" : "interest",
"size": backupLength,
"content" : backupContent
})}
{personalizedContent = personalizedContent + backupContent}
{/if}
{**Run personalization**}
{personalizedContent = personalize({
"algorithm" : "interest",
"size": 10,
"content" : personalizedContent
})}

In the Code:

<p>Here are hot items we think you'll love</p>
{foreach personalizedContent as c}
{c.title}<br/>
{/foreach}

Output:

Here are hot items with think you’ll love Item 1 Item 2 Item 3

Explanation:

This script uses the personalize() function to recommend content based on two algorithms: Interest (based on on-site browsing) and what’s popular (pieces of content that have the most purchases or the most pageviews). It starts by creating two content objects based on those algorithms: One called “interestContent”, which finds 100 items a user has displayed personal interest in; and one called “popularContent”, which is the 100 globally most popular items. Ultimately, you want an overlap of ten items to show to each user (i.e., ten items that they are interested in that are also most popular), and that recommendation length is set in the “recNum” assignment.

Next, in order to find the overlap between the two, the content_intersect() function is used to find how much content exists between “interestContent” and “popularContent”, which creates a new content object called “personalizedContent”. Then there’s a check of the length of this object (i.e., exactly how many items existed in both sections). This number is subtracted from the “recNum” value, which creates the “backupLength”. This means if there are only three matching items between the interested and popular content objects, the backupLength is “7”, meaning the script will now find seven additionally items to recommend. To check whether or not backup content is necessary, the next part of the script uses an “if” statement to check if the backupLength is greater than 0. If it is, a dedupe script is run, which uses the contains() function to check the title of every item in a data feed against an array called “usedcontent.” If the title of the item exists in the array, the filter() function removes it from the feed (this means that the title already occurred once, and it is a duplicated item).

In this example, the filter is performed twice: Once on the “personalizedContent” object, and once on the original “interestContent” object. This second filter is used to create a “backupContent” object, which is the content a user is interested in that’s not in the “popularContent” object. The personalize() function is then run on the “backupContent” object baesd on user interest, and the value of the “backupLength” number (i.e. the number of additional items needed to make it to 10) will determine how many additional items to return. “personalizedContent” is then reassigned to be the other “personalizedContent” object plus the “backupContent”. If there were 10 items or more in the original “personalizedContent” object, then no backup content gets added. Finally, personalize() is run on “personalizedContent” to get the top ten items for each user, which is then looped through using a “foreach” loop and displayed in the template.