Introduced in Feature Pack 3

Catalog storefront services programming model

The search interface can be used for retrieving information for catalog entries or performing searches. The sample catalog programming model provides a consistent service-oriented architecture (SOA) based programming model for WebSphere Commerce storefronts. It uses the WebSphere Commerce search framework and the CatalogNavigationView search noun to move storefront catalog services from beans and service-oriented integration (SOI) to SOA.

Note: As the catalog programming model uses the WebSphere Commerce search framework, search-based navigation must be enabled in starter stores to use the SOA services.

WebSphere Commerce search as a search tool

WebSphere Commerce search uses Apache Solr as a search tool, leveraging common search engine functionality in starter stores. The following list shows search engine functionality in starter stores:
  • Auto-suggest menus for suggested keywords, categories, brands, site content, and search history.
  • Auto-suggest lists for keywords.
  • Automatic search term suggestions and spelling corrections.
  • Search term highlighting.
  • Structured and unstructured content in search results.
  • Wildcard searching.

WebSphere Commerce search as a data store for the storefront

WebSphere Commerce uses Apache Solr as a data store, leveraging catalog filtering and product display pages in starter stores to browse for products (search-based navigation). This approach provides the following benefits:
  • It is faster than using a database, delivering performance gains.
  • It can run on servers other than WebSphere Commerce, balancing the workload.
The result is better performance with no additional licensing costs.

Search-based navigation enhances starter stores by triggering results when a shopper browses a storefront catalog. All immediate categories and products are returned in the results, and can also include its subcategories to increase its scope. With search-based navigation enabled, the storefront benefits include improved search performance and accuracy, search rules, and faceted navigation. As a result, the storefront delivers a perception of a personalized browsing experience in starter stores.

These additional capabilities in the storefront exist as part of the WebSphere Commerce search framework to influence starter store search results. These capabilities include:
  • Search term associations.
  • Search-based merchandising rules.
  • Starter stores integration by default.

The Catalog navigation noun that is used with the storefront Catalog service is called the CatalogNavigationView. This noun represents a business response of a catalog browsing request. It contains a list of subproducts, called CatalogEntryView, and a list of subcategories, called CatalogGroupView.

Shoppers can navigate the storefront catalog in the following ways:
  • Quick search
  • Category-based navigation
  • Faceted navigation
  • Feature Pack 6 or laterFeature Pack 4Feature Pack 2Feature Pack 3Advanced search
The following catalog entry-related data beans are moved to SOA services:
  • CatalogEntryDataBean
  • ProductDataBean
  • PackageDataBean
  • DynamicKitDataBean
  • BundleDataBean
  • ItemDataBean
Moving catalog entry-related data beans to SOA services results in a consistent programming model across the Catalog component, and simplifies storefront development, since a single noun can be used for accessing all catalog data.
Note: The CatalogEntry, CatalogGroup and Catalog nouns are used for administrative purposes, while the CatalogNavigationView noun is used in the storefront.

Catalog service overview

The product display page uses the getData tag and calls the catalog service. As WebSphere Commerce search is used to retrieve data, some of the information for the catalog entry is retrieved from the search engine and other information from the WebSphere Commerce database. The CatalogNavigationView noun is populated with data from both sources and returned in the service response. That data is then used to populate the product display page in the storefront.

The following diagram shows how the CatalogNavigationView noun works with the storefront:
Overview of catalog service

Each element in the noun either comes from the search index or the database. Access profiles determine what information comes from the database, while search profiles determine what information comes from the index.

The following elements come from the database:
  • Price
  • Components
  • MerchandisingAssociations
  • Attributes
  • DynamicKitURL
  • DynamicKitDefaultConfiguration
  • DynamicKitDefaultConfigurationComplete
  • DynamicKitModelReference
  • Title
  • MetaDescription
  • MetaKeyword
  • FullImageAltDescription
The following elements can come from the index or the database:
  • Price
  • MetaData
  • UserData
Note:
  • Where Price data comes from depends on which price display mode is selected in the wc-search.xml file.
  • MetaData is used internally.
  • UserData is for you to perform customization.

All other elements come from the search index, where elements are added to the noun by either a mediator or results filters. Various filters are defined in the search profiles in the wc-search.xml file that pull in the extra data that is required by the product display page. The results filters use a combination of index queries, command calls, and service calls to add data to the new noun elements. When possible, the results filters use search profiles to retrieve the required information from the index or database. These profiles can then be modified to return additional information with no code changes.

Implementation overview

The CatalogNavigationView noun is implemented by using the BOD Programming model and uses the same implementation concepts.

Access profiles and search profiles

Access profiles are associated with a search profile so you can specify only an access profile with the XPath query. However, you can still specify a search profile on the expression builder definition or the getData call in the JSP files to override the associated search profile. For example:

<wcf:getData type="com.ibm.commerce.catalog.facade.datatypes.CatalogNavigationViewType" var="catalogNavigationView"
             expressionBuilder="getCatalogEntryViewDetailsByID" varShowVerb="showCatalogNavigationView" scope="request">
     <wcf:param name="UniqueID" value="${catEntryID}" />
     <wcf:contextData name="storeId" data="${WCParam.storeId}" />
     <wcf:contextData name="catalogId" data="${WCParam.catalogId}" />
     <wcf:param name="searchProfile" value="MySearchProfile"/>
</wcf:getData>
The access profile provides access control and determines what information is comes from the database. The associated search profile controls information that comes from the search index. The following element is added to the wc-component.xml file, where the access profile and search profile can be linked:

<_config:configgrouping name="AccessProfileToSearchProfileMapping">
     <_config:property name="IBM_Store_Summary" value="IBM_findCatalogEntrySummary"/>
     <_config:property name="IBM_Store_Details" value="IBM_findCatalogEntryDetails"/>
     <_config:property name="IBM_Store_CatalogEntryAttachments" value="IBM_findCatalogEntryAttachments"/>
     <_config:property name="IBM_Store_CatalogEntryDetailsWithAttachments" 
       value="IBM_findCatalogEntryDetailsWithAttachments"/>
     <_config:property name="IBM_Store_CatalogEntryDetailsWithComponentsAndAttachments" 
       value="IBM_findCatalogEntryDetailsWithComponentsAndAttachments"/>
     <_config:property name="IBM_Store_CatalogEntryDetailsWithMerchandisingAssociations" 
       value="IBM_findCatalogEntryDetailsWithMerchandisingAssocDetails"/>
     <_config:property name="IBM_Store_CatalogEntryPrice" value="IBM_findCatalogEntryPrice"/>
     <_config:property name="IBM_Store_CatalogEntryPriceWithAttributes" 
       value="IBM_findCatalogEntryPriceWithAttributes"/>
     <_config:property name="IBM_Store_All" value="IBM_findCatalogEntryAll"/>
</_config:configgrouping>

Access profiles returned fields

The following table describes the access profiles and the respective fields returned by each profile.
Access profiles and returned fields
Access profile Returned fields
IBM_Store_Summary Catalog entries:
  • catalogEntryTypeCode
  • buyable
  • UniqueID
  • PartNumber
  • Name
  • ThumbNail
  • FullImage
  • ManufacturerName
  • ShortDescription
  • LongDescription
  • StoreID
  • Keyword
  • Title
  • MetaDesc
  • MetaKeyword
  • FullImageAltDescription
  • MetaData
  • UserData
Feature Pack 4 or laterCatalog groups:
  • UniqueID
  • Identifier
  • Name
  • ThumbNail
  • ShortDescription
  • MetaData
  • UserData
IBM_Store_Details

Catalog entries:

IBM_Store_Summary +

  • disallowRecurringOrder
  • SubscriptionTypeCode
  • Price
  • ParentCatalogGroupID
  • ParentCatalogEntryID
  • hasSingleSku
  • SingleSKUCatalogEntryID
  • NumberOfSKUs
  • SKUs
  • Attributes

Feature Pack 4 or laterCatalog groups:

Feature Pack 4 or laterIBM_Store_Summary +
  • LongDescription
  • FullImage
  • Title
  • MetaDescription
  • MetaKeyword
  • FullImageAltDescription
IBM_Store_CatalogEntryDetailsWithAttachments IBM_Store_Details +
  • Attachments
IBM_Store_CatalogEntryDetailsWithComponentsAndAttachments IBM_Store_CatalogEntryDetailsWithAttachments +
  • Components
  • DynamicKitURL
  • DynamicKitDefaultConfiguration
  • dynamicKitDefaultConfigurationComplete
IBM_Store_CatalogEntryDetailsWithMerchandisingAssociations IBM_Store_Details +
  • MerchandisingAssociations
IBM_Store_All IBM_Store_CatalogEntryDetailsWithComponentsAndAttachments +
  • MerchandisingAssociations
IBM_Store_CatalogEntryAttachments
  • UniqueID
  • Attachments
IBM_Store_CatalogEntryPrice
  • catalogEntryTypeCode
  • UniqueID
  • Price
IBM_findCatalogEntryPriceWithAttributes IBM_Store_CatalogEntryPrice +
  • buyable
  • StoreID
  • PartNumber
  • Name
  • ThumbNail
  • ManufacturerName
  • ShortDescription
  • Attributes

Access profiles and their corresponding search profiles

The following table shows access profiles and the corresponding search profile that are defined in the wc-search.xml file. The queries use the explicit UniqueID or PartNumber that is passed in on the XPath for the search.
Search profile mapping
Access profile Search profile
IBM_Store_Summary IBM_findCatalogEntrySummary
IBM_Store_Details IBM_findCatalogEntryDetails
IBM_Store_CatalogEntryDetailsWithAttachments IBM_findCatalogEntryDetailsWithAttachments
IBM_Store_CatalogEntryDetailsWithComponentsAndAttachments IBM_findCatalogEntryDetailsWithComponentsAndAttachments
IBM_Store_CatalogEntryDetailsWithMerchandisingAssociations IBM_findCatalogEntryDetailsWithMerchandisingAssocDetails
IBM_Store_All IBM_findCatalogEntryAll
IBM_Store_CatalogEntryAttachments IBM_findCatalogEntryAttachments
IBM_Store_CatalogEntryPrice IBM_findCatalogEntryPrice
IBM_Store_CatalogEntryPriceWithAttributes IBM_findCatalogEntryPriceWithAttributes

Search profile inheritance

The following table depicts the search profile inheritance for the catalog programming model:
Search profile inheritance
Search profile Extends from
IBM_findCatalogEntrySummary
IBM_findCatalogEntryDetails IBM_findCatalogEntrySummary
IBM_findCatalogEntryDetailsWithAttachments IBM_findCatalogEntryDetails
IBM_findCatalogEntryDetailsWithComponentsAndAttachments IBM_findCatalogEntryDetailsWithAttachments
IBM_findCatalogEntryDetailsWithMerchandisingAssocDetails IBM_findCatalogEntryDetails
IBM_findCatalogEntryAll IBM_findCatalogEntryDetailsWithComponentsAndAttachments
IBM_findCatalogEntryAttachments
IBM_findCatalogEntryPrice
IBM_findCatalogEntryPriceWithAttributes IBM_findCatalogEntryPrice
IBM_findCatalogGroupSummary
IBM_findCatalogGroupDetails IBM_findCatalogGroupSummary
The following code sample shows the IBM_findCatalogEntrySummary search profile.

<!-- Search profile for IBM_findCatalogEntrySummary-->
  <_config:profile indexName="CatalogEntry" name="IBM_findCatalogEntrySummary">
    <_config:query>
      <_config:param name="debug" value="false"/>
      <_config:param name="maxRows" value="50"/>
      <_config:param name="maxTimeAllowed" value="5000"/>
      <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchProfileNameValidator"/>
      <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchIndexNameValidator"/>
      <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchIndexSynchronizer"/>
      <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchByStorePathExpressionProvider"/>
       <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchByPublishedEntryOnlyExpressionProvider"/>
       <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchProductEntitlementExpressionProvider"/>
        <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchByCustomExpressionProvider"/>
      <_config:provider classname="com.ibm.commerce.catalog.facade.server.services.search.expression.solr.SolrSearchExpressionValidator"/>
    </_config:query>
    <_config:result>
      <_config:field name="catentry_id"/>
      <_config:field name="storeent_id"/>
      <_config:field name="buyable"/>
      <_config:field name="partNumber_ntk"/>
      <_config:field name="name"/>
      <_config:field name="thumbnail"/>
      <_config:field name="fullImage"/>
      <_config:field name="shortDescription"/>
      <_config:field name="longDescription"/>
      <_config:field name="keyword"/>
      <_config:field name="mfName_ntk"/>
      <_config:field name="catenttype_id_ntk_cs"/>
    </_config:result>
</_config:profile>

Expression builders

The UniqueIDsExpressionBuilder class is modified to support the searchProfile parameter, which can be passed in addition to the access profile. The search data mediator is modified to extract and add the UniqueID to the search query. One expression builder is created for each access profile and for both catentryID and partNumber.

Expression builders and associated access profiles
Expression builder Access profile
getCatalogEntryViewSummaryByID IBM_Store_Summary
getCatalogEntryViewSummaryByPartnumber IBM_Store_Summary
getCatalogEntryViewDetailsByID IBM_Store_Details
getCatalogEntryViewDetailsByPartnumber IBM_Store_Details
getCatalogEntryViewAttachmentsByID IBM_Store_CatalogEntryAttachments
getCatalogEntryViewAttachmentsByPartnumber IBM_Store_CatalogEntryAttachments
getCatalogEntryViewPriceByID IBM_Store_CatalogEntryPrice
getCatalogEntryViewPriceByPartnumber IBM_Store_CatalogEntryPrice
getCatalogEntryViewPriceWithAttributesByID IBM_Store_CatalogEntryPriceWithAttributes
getCatalogEntryViewPriceWithAttributesByPartnumber IBM_Store_CatalogEntryPriceWithAttributes
getCatalogEntryViewDetailsWithAttachmentsByID IBM_Store_CatalogEntryDetailsWithAttachments
getCatalogEntryViewDetailsWithAttachmentsByPartnumber IBM_Store_CatalogEntryDetailsWithAttachments
getCatalogEntryViewDetailsWithComponentsAndAttachmentsByID IBM_Store_CatalogEntryDetailsWithComponentsAndAttachments
getCatalogEntryViewDetailsWithComponentsAndAttachmentsByPartnumber IBM_Store_CatalogEntryDetailsWithComponentsAndAttachments
getCatalogEntryViewDetailsWithMerchandisingAssociationsByID IBM_Store_CatalogEntryDetailsWithMerchandisingAssociations
getCatalogEntryViewDetailsWithMerchandisingAssociationsByPartnumber IBM_Store_CatalogEntryDetailsWithMerchandisingAssociations
getCatalogEntryViewAllByID IBM_Store_All
getCatalogEntryViewAllByPartnumber IBM_Store_All
getCatalogNavigationCatalogGroupView IBM_Store_Summary
getCatalogNavigationCatalogGroupViewByIdentifier IBM_Store_Summary
getCatalogNavigationCatalogGroupViewByCatalogId IBM_Store_Summary
getCatalogNavigationCatalogGroupViewByParentCatalogGroup IBM_Store_Summary
getCatalogEntryViewSummaryByID expression builder

<expression-builder>
  <name>getCatalogEntryViewSummaryByID</name>
  <data-type-name>CatalogNavigationView</data-type-name>
  <class>com.ibm.commerce.foundation.internal.client.taglib.util.UniqueIDsExpressionBuilder</class>
  <method>formatExpression</method>
  <param>
      <name>template</name>
      <value>/CatalogNavigationView[CatalogEntryView[(UniqueID=)]]</value>
  </param>
  <param>
      <name>accessProfile</name>
      <value>IBM_Store_Summary</value>
  </param>
</expression-builder>

XPath expression

The XPath for catalog entries is /CatalogNavigationView[CatalogEntryView[ParentCatalogGroupID= and (catalogEntryTypeCode=)]]

Feature Pack 4 or laterThe XPaths for catalog groups are:
  • /CatalogNavigationView[CatalogGroupView[(UniqueID=)]]
  • /CatalogNavigationView[CatalogGroupView[(Identifier=)]]
  • /CatalogNavigationView/CatalogGroupView
  • /CatalogNavigationView[CatalogGroupView[(ParentCatalogGroupID=)]]
The CatalogNavigationView noun XPath is extended to support returning results for one or more catalog entries by catalog entry ID and part number:
  • /CatalogNavigationView[CatalogEntryView[(UniqueID=)]]
  • /CatalogNavigationView[CatalogEntryView[(PartNumber=)]]
The XPath to Solr search query mappings are defined in the wc-search.xml file.
<_config:queryMapping indexName='CatalogEntry'
     xpathKey='/CatalogNavigationView[CatalogEntryView[(UniqueID=)]]'
     searchQuery='catentry_id:(?UniqueID?)'/>

<_config:queryMapping indexName='CatalogEntry'
     xpathKey='/CatalogNavigationView[CatalogEntryView[(PartNumber=)]]'
     searchQuery='partNumber_ntk:(?PartNumber?)'/>

<_config:queryMapping indexName="CatalogEntry"
        searchQuery="parentCatgroup_id_search:?ParentCatalogGroupID?  AND catenttype_id_ntk_cs:(?catalogEntryTypeCode?)
      " xpathKey="/CatalogNavigationView[CatalogEntryView[ParentCatalogGroupID= and (catalogEntryTypeCode=)]]"/>

    <_config:queryMapping indexName="CatalogGroup"
        searchQuery="catgroup_id:(?UniqueID?)" xpathKey="/CatalogNavigationView[CatalogGroupView[(UniqueID=)]]"/>

  <_config:queryMapping indexName="CatalogGroup"
        searchQuery="identifier_ntk:(?Identifier?)" xpathKey="/CatalogNavigationView[CatalogGroupView[(Identifier=)]]"/>

    <_config:queryMapping indexName="CatalogGroup"
        searchQuery="parentCatgroup_id_facet:*_-1" xpathKey="/CatalogNavigationView/CatalogGroupView"/>

    <_config:queryMapping indexName="CatalogGroup"
        searchQuery="parentCatgroup_id_facet:(*_?ParentCatalogGroupID?)" 
        xpathKey="/CatalogNavigationView[CatalogGroupView[(ParentCatalogGroupID=)]]
      " queryComposer="com.ibm.commerce.foundation.internal.server.services.search.processor.solr.SolrSearchQueryContainingAsteriskComposer"/>

The current control parameter for access control (_wcf.ap) is used to control access and details returned.

Search index changes

To support the new noun, the following changes are made to the catalog entry search index:

<field name="longDescription" type="string" indexed="false" stored="true"  multiValued="false"/>
<field name="keyword" type="wc_text" indexed="true" stored="false"  multiValued="false"/>
<field name="disallowRecOrder" type="int" indexed="false" stored="true" multiValued="false"/>
<field name="subscripType" type="string" indexed="false" stored="true" multiValued="false"/>
Feature Pack 4 or later

<field name="parentCatgroup_id_facet" type="wc_keywordText" indexed="true" stored="true" multiValued="true"/>
<field name="sequence" type="wc_keywordText" indexed="true" stored="true" multiValued="true" />
To support the new noun, the unstructured content index indexes all attachments and are sorted according to the attachment relationship sequence number. That is, instead of sorting by relationship ID. The rulename element is mapped to attachment Usage:

<_config:mediator-property name="CatalogEntryView/Attachments/Usage" value="rulename" />