Friday, 9 January 2015

Solr Search in Websphere Commerce 7 Feature Pack 7 (Using Rest Services)



Solr Search till  Websphere Commerce Feature Pack 6
Till websphere commerce 7 feature pack 6 ,BOD-based programming model was used in the WebSphere Commerce server where the storefront accesses WebSphere Commerce to process the search request using a BOD-based message.

Please read the post on websphere-commerce-solr-search-request .


Solr Search Websphere Commerce 7 Feature Pack 7 (Using Rest Services)

The search runtime programming model introduced in Feature Pack 7 consists of a set of REST services, a search runtime framework that reuses the current search programming model, and a set of WebSphere Commerce foundation services that also provide access to the WebSphere Commerce database. Instead of using BOD and performing object-based mediation, the search programming model does not rely on any SDO, and instead uses POJO and raw data returned from the search server to perform simple name-value-pair mapping.

Solr Search Request Flow
Solr Search Request Flow




                                                  
Solr Search Response Flow
Solr Search Response Flow

WebSphere Commerce search REST APIs
The WebSphere Commerce API contains classes that are specific to WebSphere Commerce search, such as the ProductViewHandler, CategoryViewHandler, and SiteContentHandler:

ProductViewHandler (Search)
This class provides RESTful services to get the ProductView detailsThe supported search profiles are identified at runtime with the help of  Search-REST/WEB-INF/config/com.ibm.commerce.rest/wc-rest-resourceconfig.xml file. URI used  will be/search/resources/store/ instead of using the /wcs/resources/store/ .

CategoryViewHandler (Search)
This class provides RESTful services to get category data for search-based catalog navigation. The supported search profiles are identified at runtime with the help of  Search-REST/WEB-INF/config/com.ibm.commerce.rest/wc-rest-resourceconfig.xml file.URI used  will be/search/resources/store/  
instead of using the /wcs/resources/store/ .

SiteContentHandler (Search)
This class provides RESTful services to get resource details for site content. It performs the services on the WebSphere Commerce server.. The supported search profiles are identified at runtime with the help of  Search-REST/WEB-INF/config/com.ibm.commerce.rest/wc-rest-resourceconfig.xml file.URI used  will be/search/resources/store/  instead of using the /wcs/resources/store/ .

wcf:rest Tag
The wcf:rest tag sends REST requests.This JSP tag takes input and sends out REST requests, and then composes responses in a specified format. This approach is similar to the expressionBuilder in the wcf:getData tag REST access profile.

For e.g.:  In order to get a product details use  the wcf:rest tag as below

<wcf:rest var="catalogNavigationView" url="${searchHostNamePath}${searchContextPath}/store/${WCParam.storeId}/productview/byId/${productId}" >  
<wcf:param name="langId" value="${langId}"/>
<wcf:param name="currency" value="${env_currencyCode}"/>
<wcf:param name="responseFormat" value="json"/>      
<wcf:param name="catalogId" value="${WCParam.catalogId}"/>
</wcf:rest>


Solr Search Customizations Example
Customize the rest service call to make use of a custom search profile in Websphere Commerce 7 FeaturePack7.

In the below example we are trying to customize by making use of custom search profile Ext_IBM_findProductByIds_Summary.

Step 1: Create a new search profile “Ext_IBM_findProductByIds_Summary”

Create a folder Search\xml\config\com.ibm.commerce.catalog-ext.
Copy the wc-search.xml from Search\xml\config\com.ibm.commerce.catalog 

Add the following profile configuration before the end tag </_config:search-config>:
<_config:profile name="Ext_IBM_findProductByIds_Summary" extends="IBM_findProductByIds_Summary">
<_config:query inherits="true">
<_config:postprocessor
       classname="com.ibm.commerce.foundation.server.services.rest.search.postprocessor.solr.SolrRESTSearchCatalogEntryViewUserDataQueryPostprocessor" />        
</_config:query>
<_config:result inherits="true">
<_config:field name=" customData" />
</_config:result>              
</_config:profile>




Step2: Add the new search profile into Search-Rest configuration

In order to allow websphere commerce Search server to accept new search profile, you need add the new search profile  into the Search-Rest configuration.

Create a folder to keep the custom rest configuration file (wc-rest-resourceconfig.xml) in Search-Rest\WebContent\WEB-INF\config\com.ibm.commerce.rest-ext
Copy wc-rest-resourceconfig.xml from in  Search-Rest\WebContent\WEB-INF\config\com.ibm.commerce.rest folder to  com.ibm.commerce.rest-ext folder

Add the below section so that new search profile is available with the rest services.

<GetUri uri="store/{storeId}/productview/byIds"
description="Get products by unique IDs"
searchProfile="<existing  search profile list…..> , Ext_IBM_findProductByIds_Summary“>

Step 3: Customize the pre-processor


Pre-processor will read values from custom table(CUSTOM_TABLE) and populates the temporary table(XI_EXT_TABLE) .These temporary table values will be used for building the index.

Go to WC_installdir /instances/ instance_name /search\pre-processConfig\MC_ masterCatalogId\databaseType

For e.g.: WC_installdir /instances/ instance_name /search/pre-processConfig/MC_10001/DB2

Create a custom preprocessor file wc-dataimport-preprocess-custom.xml with the below contents.

<_config:data-processing-config processor="com.ibm.commerce.foundation.dataimport.preprocess.StaticAttributeDataPreProcessor" masterCatalogId="10001" fetchSize="500" batchSize="500">
<_config:table definition="CREATE TABLE  XI_EXT_TABLE (CATENTRY_ID BIGINT NOT NULL, CUSTOMDATA VARCHAR(256) ,PRIMARY KEY (CATENTRY_ID))" name=" XI_EXT_TABLE"/>
<_config:query sql="SELECT CUSTOMDATA, CATENTRY_ID FROM  CUSTOM_TABLE"/>
<_config:mapping>
<_config:key queryColumn="CATENTRY_ID" tableColumn="CATENTRY_ID"/>
<_config:column-mapping>
<_config:column-column-mapping>                            
<_config:column-column queryColumn="CUSTOMDATA " tableColumn=" CUSTOMDATA"/>
</_config:column-column-mapping>
</_config:column-mapping>
</_config:mapping>          
</_config:data-processing-config>

Step 4: Update new solr fields in schema.xml

Update  the \solr\home\MC_10001\en_US\CatalogEntry\conf\schema.xml
Add below lines to keep the customData in ndex.

<field name="customData" type="string" indexed="true" stored="true"  multiValued="true"/>

Indexed – only indexed field can be searchable in Solr.
Stored – If the value is true, we can retrieve its values through Solr request. You can’t see its value if you set it as false.
multivalued – This defines whether you want to set this value as an array to hold multiple values.

Step 5: Data import Handler(DIH) configuration  in wc-data-config.xml

Data import Handler will be called during build index and it is used to read values from temporary tables and build the index.

Update wc-data-config.xml in  \solr\home\MC_10001\en_US\CatalogEntry\conf

Add additional line in SELECT clause to return the custom Data.

XI_EXT_TABLE.CUSTOMDATA AS CUSTOMDATA

Add the left outer join line in the FROM clause

LEFT OUTER JOIN   XI_EXT_TABLE ON  CATENTRY.CATENTRY_ID= XI_EXT_TABLE.CATENTRY_ID

Add below line for mapping table fields to indexed fields.
<field column="CUSTOMDATA" name=" customData"/>        

Step 6: Modify the user data field name mapping to map the CustomData field to a user data.

Navigate to the com.ibm.commerce.catalog-ext directory under the search server. If this directory does not exist, you must create the directory.
Search_eardir\xml\config\com.ibm.commerce.catalog-ext
Open the wc-component.xml file. If it does not exist, you must create this file.

Add the following mapping:

<?xml version="1.0" encoding="UTF-8"?>
<_config:DevelopmentComponentConfiguration
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ibm.com/xmlns/prod/commerce/foundation/config ../xsd/wc-component.xsd "
xmlns:_config="http://www.ibm.com/xmlns/prod/commerce/foundation/config">
<_config:valuemappingservice>
<_config:valuemapping externalName="CatalogEntryUserDataFieldNameMapping"
internalName="CatalogEntryUserDataFieldNameMapping">
<_config:valuemap externalValue="CustomData " internalValue="customData" />
</_config:valuemapping>
</_config:valuemappingservice>
</_config:DevelopmentComponentConfiguration>


Step 7: Update JSP for new search profile and read the custom data  from UserData section of noun.

<wcf:rest var="catalogNavigationView" url="${searchHostNamePath}${searchContextPath}/store/${WCParam.storeId}/productview/byId/${productId}" >    
<wcf:param name="langId" value="${langId}"/>
<wcf:param name="currency" value="${env_currencyCode}"/>
<wcf:param name="responseFormat" value="json"/>      
<wcf:param name="catalogId" value="${WCParam.catalogId}"/>

<wcf:param name="profileName" value="Ext_IBM_findProductByIds_Summary" />
</wcf:rest>

<c:set var="customData" value="" />
<c:forEach var="userData" items="${catalogEntryDetails.UserData}" >
<c:if test="${!empty userData.CustomData}">
<c:set var="customData" value="${userData.CustomData}" />
</c:forEach>
</c:if>

1 comment:

  1. I am new to solr search with WCS want to know what is the difference between wc-search.xml and wc-component.xml

    ReplyDelete