Introduction
There are the following use cases for recommendation engines:
Substitute products:
- (1) Based on attribute similarity. It can rely on the properties of the item(s), which are analyzed to determine what else the user may like.
- Example: Apple iPhone 6 and Samsung Galaxy S6 are substitutes because they have many similar or identical characteristics (product attributes).
- (2) Based on association rules
- Example: Coke and Pepsi are substitutes. Note that it requires manual work to connect them into a group.
- (1) Based on attribute similarity. It can rely on the properties of the item(s), which are analyzed to determine what else the user may like.
Complementary products
- (3) Based on collaborative filtering (frequently bought together)
- Example: IPA beer and Kettle Jalapeño chips are complementary products because people like to buy them together.
- (4) Based on association rules (for co-purchased products)
- Example: IPA beer and Lays are complementary products because the merchant wants to sell more Lays than Kettle.
- (3) Based on collaborative filtering (frequently bought together)
Hybris out of the box supports #2 and #4, but the association rules in it are extremely basic: simple product linking SKU <-> SKU. In hybris, you need to manually select other up-sell/cross-sell products or use an external tool. This means that in order to link five digital cameras with a dozen memory cards, you need to manually or automatically create 24×5=120 product reference records. The number of records becomes much larger for large product catalogs.
The other two approaches mentioned, collaborative filtering and attribute similarity, are out of scope for this post. The algorithms used there are good for large amounts of data and traffic. The main goal of a recommendation engine of this kind is to extract new knowledge from available sources, such as the PIM database, CRM, and webserver logs, and use it to enrich the customer experience and increase sales.
The purpose of this article is to show a PoC of a recommendation system based on the rule engine. Hybris already has a powerful rule engine for product promotion management, so I decided to reuse it for the recommendation system.
Solution
There are two pieces of functionality:
- Rule builder for the promotion engine
- Recommendation engine
As you can see in the diagram below, these modules are not connected to each other. The builder produces the rules, and the recommendation engine uses them.
Rules
There are some examples of rules that are already available in the system:
- If you visit a product page with one of the Film Camera products, the system must recommend color and black & white films as complementary products, if any.
- If the product has “memory stick” in the “Supported memory cards” classification attribute, the system must recommend the Memory Stick products, if any.
- For Products X, Y, Z, the system must recommend products from categories A and B, except products with the attribute N=<something>.
Actually, the range of possible rules is truly indefinite. The hybris rule builder allows you to customize the conditions and actions.
If more than one rule is fulfilled, the results will be mixed.

Rule Builder
Rule Builder was initially designed for promotions. It was a brand-new product: SAP added it to hybris in April 2016, in version 6.0.
In order to use it for product recommendation rules, I added custom conditions and actions.
Generating recommended products
This module uses the hybris Drools engine to evaluate rules against products, one or more at a time. The result is a SOLR request.
Custom Conditions
For the demo, I created two custom conditions:
- Product title condition
- Product classification attribute condition
It is easy to create a universal product condition that deals with all available product attributes.
It is important that, in my solution, conditions work with ProductModel attributes for filtering, while actions deal with indexed properties.
Custom actions
For the demo, I created one custom action:
- Filter all products with specified indexed properties.
Post processing
The resulting SOLR request is a merge of the rule outputs.
Video
Architecture

Technical details
Impex
$lang=en
INSERT_UPDATE RuleConditionDefinition;id[unique=true];name[lang=en];priority;breadcrumb[lang=$lang];allowsChildren;translatorId;translatorParameters;categories(id)
;producttitle;Product title;200;Product;false;simpleProductAttributeConditionTranslator;;general
;Example_Compatible_memory_cards;Compatible memory cards;200;Product;false;extProductAttributeConditionTranslator;;general
INSERT_UPDATE RuleConditionDefinitionParameter;definition(id)[unique=true];id[unique=true];priority;name[lang=$lang];description[lang=$lang];type;value;required[default=true];
#y_cart_total;operator;1100;Operator;Operator to compare the cart total value;Enum(de.hybris.platform.ruledefinitions.AmountOperator);"""GREATER_THAN_OR_EQUAL""";
;producttitle;titlestr;1000;Title Substring;Title Substring;java.lang.String;;
;Example_Compatible_memory_cards;comp_mc;1001;Example Compatible memory cards (Substring);Example Compatible memory cards (Substring);java.lang.String
INSERT_UPDATE RuleConditionDefinitionRuleTypeMapping;definition(id)[unique=true];ruleType(code)[unique=true]
;producttitle;PromotionSourceRule
;Example_Compatible_memory_cards;PromotionSourceRule
#ACTIONS
$lang=en
INSERT_UPDATE RuleActionDefinitionCategory;id[unique=true];name[lang=$lang];priority
;recommendations;recommendations;700
INSERT_UPDATE RuleActionDefinition;id[unique=true];name[lang=$lang];priority;breadcrumb[lang=$lang];translatorId;translatorParameters;categories(id)
;recommend_products;Add products to recommendations;200;Add product to recommendations;ruleExecutableActionTranslator;actionId->ruleAddProductsToRecommendedAction;recommendations
INSERT_UPDATE RuleActionDefinitionParameter;definition(id)[unique=true];id[unique=true];priority;name[lang=$lang];description[lang=$lang];type;value;required[default=true]
;recommend_products;solrProperty;100;Solr Property;Solr Property;ItemType(SolrIndexedProperty);
;recommend_products;solrExpression;101;solrExpression;solrExpression;Enum(de.hybris.ruleenginetrail.enums.ActionOperator);
;recommend_products;value;102;Value of the Field;Product Title Substring;java.lang.String;;
INSERT_UPDATE RuleActionDefinitionRuleTypeMapping;definition(id)[unique=true];ruleType(code)[default=PromotionSourceRule][unique=true]
;recommend_products;Classes
Custom ProductRAO populator. Converts
ProductModeltoProductRAO. By default, only “code” and “supercategories” are populated. I added all the remaining product properties, including classification attributes.Custom Product Attribute Condition Translators. These classes are used to convert the values from the condition parameters (see Impex) into
DroolsRules— more precisely, into theRuleIrConditionused for Drools rule composition. I created two custom translators as examples: one for the product title and one for the product classification attribute. It is trivial to convert this into something more comprehensive.Custom Rule Executable Action. I use only one type of action, “ProductsToRecommend”. This action is executed each time the rule condition is fulfilled. Internally, all this class does is add
ProductToRecommendRAOwith configurable rule-dependent data as a fact.ProductToRecommendRAO item type. I used only one custom attribute here,
solrCondition(Map type). This structure is used for messages from actions back to the controller or service. The messages contain the Solr attribute name and value.
© Rauf Aliev, August 2016