Skip to Content

I work in the SAP Marketing development team. My team develops the SAP Marketing Recommendation solution. Our solution includes a set of standard delivery recommendation algorithms. Understandably, these algorithms cannot meet every individual use case our customers have. However, customers can leverage the extensibility capabilities of SAP Marketing Cloud  to use their own custom recommendation algorithms. This blog illustrates an end to end flow of how to import an HANA calculation view and use it in a custom recommendation algorithm in the SAP Marketing Recommendation solution.

 

Use Case:

As a marketer, I would like to replace a recommended product provided by a recommendation model by another product.

Solution: Leverage the SAP Extensibility Features in SAP Marketing Cloud to do the following:

Create and Populate Custom Business Object

You must be assigned the Administrator business role to perform the following tasks:

  1. Open the Custom Business Objects

  1. Choose New to create a custom business object.

Note: Make sure to check UI Generation and Service Generation.

  1. Choose Go to Fields and Logic to add fields to your custom business object.

For the purposes of this scenario, two fields are required: PRODUCT_FROM and PRODUCT_TO. These fields store the product DB Keys (UUIDs).

Note: In production, you might want to use the semantic key of a product. For example,  the Product Origin and Product ID pair for both PRODUCT_FROM and PRODUCT_TO. Additionally, when implementing the SAP HANA view, these semantic keys need to be converted into the product DB key (UUID).

  1. Navigate back to Custom Business Object details screen and choose Publish.
  2. Choose Maintain Catalog and Add a business catalog to the custom business object. For the purposes of this scenario, add the Marketing – Recommendation (SAP_CEC_BC_MKT_REC_PC) business catalog.

If the business role assigned to your user contains the assigned business catalog; you will be able to see a tile on your launch pad that allows you to access your custom business object. For example, in this scenario a Marketing Expert has access to the tile of this custom business object, as a result of the assigning the Marketing – Recommendation business catalog.

  1. Close the Custom Catalog Extensions

You can also choose Go To Generated UI on the Custom Business Object page to access the Custom Business Object UI. For the purpose of this scenario add the following:

PRODUCT_FROM:                2CC9F458CFF8071EE10000000A770004 (SAP_HYBRIS_PRODUCT, M13254)

PRODUCT_TO:                        29C9F458CFF8071EE10000000A77004 (SAP_HYBRIS_PRODUCT, M26401)

Note: Although we are only mapping one product to another in this scenario, you can add as many entries as your scenario requires.

  1. Choose Go to make the entries appear.

  1. You can also import data via OData service if you checked the Service Generation check box on the Custom Business Object details page. Here is a sample url to the service – https://[server:port]/sap/opu/odata/sap/YY1_ PRODUCT_MAP_CDS/$metadata.

For more information, see http://help.sap.com/mkt Choose Integration -> Integration Guide -> Integration Services -> Import of Data into Custom Business Object.

Create and Import Custom SAP HANA View

You must be assigned the Administrator_MKT business role to perform the following tasks:

  1. Open the Add Custom View

  1. Choose Export Table Definition.
    1. Enter YY1_PRODUCT_MAPas the Table Name, and then choose the Load Table.
    2. Choose Export Table.

This will return the SQL create statement of the table in the backend for this custom business object. For example, in this scenario the table name in the backend is YY1_F00BECF19217. Use this SQL statement to create the table in your SAP HANA tenant.

  1. Choose Export View Definition.
    • Choose Recommendation Runtime as the View Usage Type.
    • Choose CA_CUAN_PRODUCT_TO_CUAN_PRODUCT_RUNTIME as the View Name.
    • Choose Load View.
    • Choose Export View.

A zip file is downloaded. You can now use the sample implementation of the SAP HANA View for the Recommendation Runtime view. Import this view into your SAP HANA tenant. The sample view contains some mandatory database tables for SAP Marketing Recommendations that are now created in your SAP HANA tenant. For example, PRECO_CX_TASK.

  1. Go to your SAP HANA tenant and implement a calculation view and export it as an XML file (see example below).

Confirm the following after export:

  • Every occurrence of schemaName is set to ABAP (highlighted in red in the example below).
  • Ensure that columnObjectName= <your table here> (highlighted in green in the example below) is set to the column table name from step 2.b of this process.
  • Also note that Z_PRECO_PRODUCT_MAP (highlighted in blue in the example below) is the name of the custom algorithm you will be creating shortly. The algorithm name bust be unique and respect a naming convention that starts with Z_.

 

<?xml version=”1.0″ encoding=”UTF-8″?>

<Calculation:scenario xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:AccessControl=”http://www.sap.com/ndb/SQLCoreModelAccessControl.ecore” xmlns:Calculation=”http://www.sap.com/ndb/BiModelCalculation.ecore” schemaVersion=”2.3″ id=”ZPRECO_PRODUCT_MAP” applyPrivilegeType=”ANALYTIC_PRIVILEGE” checkAnalyticPrivileges=”true” defaultClient=”$$client$$” defaultLanguage=”$$language$$” hierarchiesSQLEnabled=”false” translationRelevant=”true” visibility=”internal” calculationScenarioType=”TREE_BASED” dataCategory=”DIMENSION” enforceSqlExecution=”false” executionSemantic=”UNDEFINED” outputViewType=”Projection”>

  <origin system=”XTK:LDDBXTK.WDF.SAP.CORP:02:SINGLEDB:LIQIU”/>

  <descriptions defaultDescription=”ZPRECO_PRODUCT_MAP”/>

  <localVariables/>

  <variableMappings/>

  <informationModelLayout relativeWidthScenario=”36″/>

  <dataSources>

    <DataSource id=”PRECO_CX_RESULTS” type=”DATA_BASE_TABLE”>

      <viewAttributes allViewAttributes=”true”/>

      <columnObject schemaName=”ABAP” columnObjectName=”PRECO_CX_RESULTS”/>

    </DataSource>

    <DataSource id=”PRECO_CX_TASK” type=”DATA_BASE_TABLE”>

      <viewAttributes allViewAttributes=”true”/>

      <columnObject schemaName=”ABAP” columnObjectName=”PRECO_CX_TASK”/>

    </DataSource>

    <DataSource id=”YY1_F00BECF19217″ type=”DATA_BASE_TABLE”>

      <viewAttributes allViewAttributes=”true”/>

      <columnObject schemaName=”ABAP” columnObjectName=”YY1_F00BECF19217“/>

    </DataSource>

  </dataSources>

  <calculationViews>

    <calculationView xsi:type=”Calculation:ProjectionView” id=”TASK”>

      <descriptions/>

      <viewAttributes>

        <viewAttribute id=”TASK_ID”/>

        <viewAttribute id=”MAX_RESULT”/>

        <viewAttribute id=”ENGINE_ID”/>

        <viewAttribute id=”ALGO_TYPE_ID”>

          <filter xsi:type=”AccessControl:SingleValueFilter” including=”true” value=”Z_PRECO_PRODUCT_MAP”/>

        </viewAttribute>

        <viewAttribute id=”ALGO_TYPE_ID_1″/>

      </viewAttributes>

      <calculatedViewAttributes/>

      <input node=”#PRECO_CX_TASK”>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”TASK_ID” source=”TASK_ID”/>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”MAX_RESULT” source=”MAX_RESULT”/>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”ENGINE_ID” source=”ENGINE_ID”/>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”ALGO_TYPE_ID” source=”ALGO_TYPE_ID”/>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”ALGO_TYPE_ID_1″ source=”ALGO_TYPE_ID”/>

      </input>

    </calculationView>

    <calculationView xsi:type=”Calculation:JoinView” id=”RESULT” joinType=”inner”>

      <descriptions/>

      <viewAttributes>

        <viewAttribute id=”TASK_ID”/>

        <viewAttribute id=”RESULT_ITEM”/>

        <viewAttribute id=”RESULT_ITEM_TYPE”/>

        <viewAttribute id=”SCORE”/>

        <viewAttribute hidden=”true” id=”JOIN$ENGINE_ID$ENGINE_ID”/>

      </viewAttributes>

      <calculatedViewAttributes/>

      <input node=”#PRECO_CX_RESULTS”>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”RESULT_ITEM” source=”RESULT_ITEM”/>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”RESULT_ITEM_TYPE” source=”RESULT_ITEM_TYPE”/>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”SCORE” source=”SCORE”/>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”JOIN$ENGINE_ID$ENGINE_ID” source=”ENGINE_ID”/>

      </input>

      <input node=”#TASK”>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”TASK_ID” source=”TASK_ID”/>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”JOIN$ENGINE_ID$ENGINE_ID” source=”ENGINE_ID”/>

      </input>

      <joinAttribute name=”JOIN$ENGINE_ID$ENGINE_ID”/>

    </calculationView>

    <calculationView xsi:type=”Calculation:ProjectionView” id=”PRODUCT_MAP”>

      <descriptions/>

      <viewAttributes>

        <viewAttribute id=”CLIENT”>

          <filter xsi:type=”AccessControl:SingleValueFilter” including=”true” value=”$$client$$”/>

        </viewAttribute>

        <viewAttribute id=”PRODUCT_FROM”/>

        <viewAttribute id=”PRODUCT_TO”/>

      </viewAttributes>

      <calculatedViewAttributes/>

      <input node=”#YY1_F00BECF19217″>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”CLIENT” source=”CLIENT”/>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”PRODUCT_FROM” source=”PRODUCT_FROM”/>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”PRODUCT_TO” source=”PRODUCT_TO”/>

      </input>

    </calculationView>

    <calculationView xsi:type=”Calculation:JoinView” id=”MAPPED_RESULT” joinType=”leftOuter”>

      <descriptions/>

      <viewAttributes>

        <viewAttribute id=”TASK_ID”/>

        <viewAttribute id=”RESULT_ITEM_TYPE”/>

        <viewAttribute id=”SCORE”/>

        <viewAttribute id=”PRODUCT_TO”/>

        <viewAttribute id=”RESULT_ITEM_ORIGIN”/>

      </viewAttributes>

      <calculatedViewAttributes>

        <calculatedViewAttribute datatype=”VARCHAR” id=”RESULT_ITEM” length=”16″ expressionLanguage=”COLUMN_ENGINE”>

          <formula>if(isnull(&quot;PRODUCT_TO&quot;),&quot;RESULT_ITEM_ORIGIN&quot;, &quot;PRODUCT_TO&quot;)</formula>

        </calculatedViewAttribute>

      </calculatedViewAttributes>

      <input node=”#RESULT”>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”TASK_ID” source=”TASK_ID”/>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”RESULT_ITEM_TYPE” source=”RESULT_ITEM_TYPE”/>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”SCORE” source=”SCORE”/>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”RESULT_ITEM_ORIGIN” source=”RESULT_ITEM”/>

      </input>

      <input node=”#PRODUCT_MAP”>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”PRODUCT_TO” source=”PRODUCT_TO”/>

        <mapping xsi:type=”Calculation:AttributeMapping” target=”RESULT_ITEM_ORIGIN” source=”PRODUCT_FROM”/>

      </input>

      <joinAttribute name=”RESULT_ITEM_ORIGIN”/>

    </calculationView>

  </calculationViews>

  <logicalModel id=”MAPPED_RESULT”>

    <descriptions/>

    <attributes>

      <attribute id=”TASK_ID” order=”1″ attributeHierarchyActive=”false” displayAttribute=”false”>

        <descriptions defaultDescription=”TASK_ID”/>

        <keyMapping columnObjectName=”MAPPED_RESULT” columnName=”TASK_ID”/>

      </attribute>

      <attribute id=”RESULT_ITEM_TYPE” order=”2″ attributeHierarchyActive=”false” displayAttribute=”false”>

        <descriptions defaultDescription=”RESULT_ITEM_TYPE”/>

        <keyMapping columnObjectName=”MAPPED_RESULT” columnName=”RESULT_ITEM_TYPE”/>

      </attribute>

      <attribute id=”SCORE” order=”3″ attributeHierarchyActive=”false” displayAttribute=”false”>

        <descriptions defaultDescription=”SCORE”/>

        <keyMapping columnObjectName=”MAPPED_RESULT” columnName=”SCORE”/>

      </attribute>

      <attribute id=”RESULT_ITEM” order=”4″ attributeHierarchyActive=”false” displayAttribute=”false”>

        <descriptions defaultDescription=”RESULT_ITEM”/>

        <keyMapping columnObjectName=”MAPPED_RESULT” columnName=”RESULT_ITEM”/>

      </attribute>

    </attributes>

    <calculatedAttributes/>

    <privateDataFoundation>

      <tableProxies/>

      <joins/>

      <layout>

        <shapes/>

      </layout>

    </privateDataFoundation>

    <baseMeasures/>

    <calculatedMeasures/>

    <restrictedMeasures/>

    <localDimensions/>

  </logicalModel>

  <layout>

    <shapes>

      <shape expanded=”true” modelObjectName=”Output” modelObjectNameSpace=”MeasureGroup”>

        <upperLeftCorner x=”99″ y=”87″/>

        <rectangleSize/>

      </shape>

      <shape expanded=”true” modelObjectName=”RESULT” modelObjectNameSpace=”CalculationView”>

        <upperLeftCorner x=”176″ y=”261″/>

        <rectangleSize height=”-1″ width=”-1″/>

      </shape>

      <shape expanded=”true” modelObjectName=”TASK” modelObjectNameSpace=”CalculationView”>

        <upperLeftCorner x=”176″ y=”357″/>

        <rectangleSize height=”-1″ width=”-1″/>

      </shape>

      <shape expanded=”true” modelObjectName=”PRODUCT_MAP” modelObjectNameSpace=”CalculationView”>

        <upperLeftCorner x=”22″ y=”261″/>

        <rectangleSize height=”-1″ width=”-1″/>

      </shape>

      <shape expanded=”true” modelObjectName=”MAPPED_RESULT” modelObjectNameSpace=”CalculationView”>

        <upperLeftCorner x=”99″ y=”165″/>

        <rectangleSize height=”96″ width=”140″/>

      </shape>

    </shapes>

  </layout>

</Calculation:scenario>

 

  1. Return to the Add Custom View
    • Choose Import View Definition.
    • Enter Recommendation Runtime as the View Usage Type.
    • Choose the .xml file you exported in the previous step as the View Name.
    • Choose Import View.

Create Custom Recommendation Algorithm

You must be assigned the BPC_EXPERT business role to perform the following tasks:

  1. Open the Manage Your Solution

  1. Choose Configure Your Solution.
  2. Choose Commerce Marketing in the Marketing Application Area.

  1. Configure the Recommendation Algorithms

  1. Choose + to Add a Product Recommendation Algorithm.
  2. Enter the ID that was used in the calculation view you exported in step 4 of the previous process (Z_PRECO_PRODUCT_MAP).
  3. Enter a Name.
  4. Choose the calculation view you imported in the last step of the previous process as the Runtime SAP HANA View.

For more information, see http://help.sap.com/mkt Choose Operations -> Administration Guide -> Configuration Apps -> Commerce Marketing -> Recommendations Algorithms.

 

Use the Custom Recommendation Algorithm in a Recommendation Model

As a user who is assigned to the Business_Analyst_MKT business role, I performed the following tasks in Recommendation Models to demonstrate how the tasks we have performed to date achieve the desired outcome of the scenario.

  1. In the Recommendations Models application, I created a model.

  1. A preview of the model demonstrates that it produces a single recommendation: Product M13254.

  1. I added an additional Convert step to the model and added the custom algorithm we created in the previous process.

  1. By performing another preview, you can see that the final recommendation produced by this model is now product M26401, instead of M13254. This is the result of the product mapping we introduced in the custom algorithm contained in the Convert

 

By following the steps illustrated in this blog, you shall become more familiar with the extensibility capabilities of SAP Marketing Cloud Recommendation and shall be able to import your HANA calculation view into SAP Marketing Cloud and use it in a custom recommendation algorithm in the SAP Marketing Recommendation solution.

In the future, I will continue publishing blogs with regard to the SAP Marketing Recommendation solution.

To report this post you need to login first.

1 Comment

You must be Logged on to comment or reply to a post.

Leave a Reply