Recommendations are a key feature of personalization. Even though there are many templates to choose from and additional filters to apply, sometimes the results still don't meet our expectations, and we need to post-filter them with Jinja. Today, we'll focus on handling the attribute value model_fallback.
What is model_fallback?
In your results, you'll see an additional attribute called recommendation_source, which can have one of two values: model_personalized or model_fallback.
This attribute indicates how the AI engine generated the recommendation. Suppose a customer lacks interaction data (for example, no purchase_item events for a "Customers Who Bought Also Bought" model). In that case, the engine falls back to recommending the most frequently interacted-with items based on the same event type.
Unlike fillWithRandom, this type of fallback can't be turned off. That means we must handle it differently, which we'll do by post-filtering with Jinja.
How do you exclude items with such an attribute?
Let's start by pulling 20 items from the recommendation. Typically, we'll need to reference the item ID in the request.
{% set recos = recommendations('RecommendationID', 20, items = { 'item_123': 1 }) %}I'd like you to please read more about our integration of recommendations documentation.
Then we go through each item in the list called "recos", as we have defined. If the item's recommendation_source isn't model_fallback, then we show that item's title, price, and link:
{% set recos = recommendations('RecommendationID', 20, items = { 'item_123': 1 }) %}
{% for item in recos %}
{% if item.recommendation_source != "model_fallback" %}
{{ item.title }} for {{ item.price }} at {{ item.url }}!
{% endif %}
{% endfor %}We can also adjust the if condition in this way, assuming we only want the personalized items:
{% if item.recommendation_source == "model_personalized" %}Aborting the entire campaign if there aren't enough personalized items
Sometimes you might want to abort the entire campaign. For example, if you've decided to send only personalized items, you wouldn't want to send an empty email. To do that, you can use the following snippet:
{% set recos = recommendations('RecommendationID', 20, items = { 'item_123': 1 }) %}
{% set recos_string = recos | string %}
{% set count = recos_string.count('model_personalized') %}
{% if count > 2}
All needed code or text.
{% else %}
{% abort: "Not enough model_personalized items" %}
{% endif %}
Like the previous snippet, we take items from a recommendation and turn them into a string. We'll send the campaign if this string contains more than two model_personalized items. If it contains fewer than two model_personalized items, we'll abort and show the message "Not enough model_personalized items." This will also create a campaign event, making tracking why a customer didn't receive an email/communication easier.
Important: If you want to stop the campaign without creating an event (to avoid unnecessary storage usage), you can use {% abort %}. However, remember that this means you won't be able to track which customers were not sent the campaign.
Read more about the abort function here.
You may have noticed that you can connect these two snippets by replacing all needed code or text with the initial snippet that excludes model_fallback items:
{% set recos = recommendations('RecommendationID', 20, items = { 'item_123': 1 }) %}
{% set recos_string = recos | string %}
{% set count = recos_string.count('model_personalized') %}
{% if count > 2}
{% for item in recos %}
{% if item.recommendation_source != "model_fallback" %}
{{ item.title }} for {{ item.price }} at {{ item.url }}!
{% endif %}
{% endfor %}
{% else %}
{% abort: "Not enough model_personalized items" %}
{% endif %}With the above code, you are now pulling items from recommendations, checking if you have enough personalized items (if not, you abort), and returning title, price, and link for them.
Please note that the code may require adjustments to fit your use case.