Improve the performance of dynamic SKU auto-suggestion

Browser cache capability for quick order forms in WebSphere Commerce V7.2

This article presents a browser cache solution to reduce server requests, improve the speed of auto-suggest, and implement dynamic SKU suggestions on the quick order page of a WebSphere Commerce® starter store. WebSphere Commerce V7.2 includes a search box in the site navigation header that uses the Apache Solr search to drive the auto-suggest feature. This feature requires calls to the search server to retrieve suggested keywords for every user keystroke. This browser cache solution reduces the performance impact on the server that is caused by the Ajax calls to the Apache Solr search server for every keystroke.

Share:

Junmin Liu (junmin.liu@us.ibm.com), Advisory IT Specialist, IBM

A photo of the author Junmin LiuJunmin Liu is a Software Engineer who specializes in object-oriented design and analysis, database modeling, Java Platform, Enterprise Edition development and web programming. Junmin is fluent in a variety of languages including Java, PHP, Ruby and Perl, with extensive experience software development and a passion for Agile or XP development methodologies. He published several articles in the bioinformatics and database-related fields. He is also a co-author of several open source bioinformatics projects with developers from University of Pennsylvania, Stanford University, and Harvard University.



24 April 2013

Overview

The steps outlined in this article cover all the steps that are needed to add a browser cache capability. The browser cache capability reduces the search server requests and improves the auto-suggest performance of the SKU suggest feature for the quick order form in the Commerce starter store.

Apache Solr is an open source enterprise search platform that is based on the Apache Lucene project. It has a REST-like API for both administration and query. In WebSphere Commerce V7.2 and above, the search functionality uses Apache Solr as a search tool and the Commerce starter store for a common search engine. One of the search engine functions in the starter store is an auto-suggest menu for suggesting keywords, categories, brands, site content, and search history.

The auto-suggest menu provides search assistance for the customer's input. When a customer begins typing in the search box, an event listener (onkeyup) calls a JavaScript™ function in the StoreCommonUtilities.js file. The StoreCommonUtilities.js file contains the logic to handle the auto-suggest menu. With each keystroke, the JavaScript invokes an Ajax call to perform the suggested keyword matches that are retrieved from the search index and displayed in the menu. Customers can save time by selecting the applicable keyword in the list to perform the search.

Understanding cache and auto-suggest design

There are different ways to make auto-complete suggestions with Solr. The most common practice is based on indexed data. The SKU auto-suggest uses Solr’s SearchComponent, which is a simple term component that provides access to the indexed terms in a field and the number of documents that match each term. Searching terms in index order is fast since the implementation directly uses the index engine’s TermEnum to loop through the term dictionary.

Theoretically, in a multitier web application architecture, caching takes place in the tier closest to the user in order to maximize the benefit of cache. The DynaCache on JSP view level is not useful for keyword suggestion since the user input space is too big. And there is also a cache invalidation issue for SKU data because SKU data can be frequently changed. Based on these reasons the web page level cache strategy is being used instead, which has the following advantages when compared to dynamic cache on the Commerce server side:

  • Caching takes place in web page that is the tier closest to the user.
  • Generating cache dynamically avoids issues with cache invalidation.

Figure 1 highlights the design of an auto-suggest menu with cache capability. The result of a Solr search is stored as a JSON HashMap data structure with search input as the HashMap key. The length of the HashMap key is equal to the minimum length required to trigger the Ajax call to Solr server. Any search input that contains the HashMap key triggers the search locally instead.

For example, if minimum length is set to 2 and user types in “AC” that triggers an Ajax call to Solr search server. The result of the server call is stored locally with “AC” as the keyword and then any keywords that have “AC” as a prefix such as “ACA”, “ACG” and “ACA-” does will not trigger an additional Ajax call. Instead, it performs a string match against the SKU list that is locally stored in the browser.

Figure 1. Design of browser cache and auto-suggest
The design diagram of the browser cache and auto-suggest.

Configuring an auto-suggest menu

Step 1: Create a JSP view with an Ajax call proxy

The Solr server can be hosted remotely with a different domain name than the WebSphere Commerce server. This results in security issues that do not allow a cross-domain Ajax call. It is for that reason that you need to create a struts action and JSP page that acts as proxy to the Solr search server.

Listing 1. Definition of struts action and action forward
<forward 
className="com.ibm.commerce.struts.ECActionForward"  
name="QuickOrderAutoSuggestionView/10001" 
path="/ShoppingArea/OrderCreationSection/QuickOrderSubsection/QuickOrderSuggestion.jsp"/>

<action 
path="/QuickOrderAutoSuggestionView" 
type="com.ibm.commerce.struts.BaseAction"/>

Step 2: Set the view access control

By default the view page is not accessible by guest users, so we need to set access control for QuickOrderAutoSuggestionView to ‘AllSiteUsersView’ which allows all types of users access to the view. In the SQL listing below, we make the assumption that there a row with an acactgrp_id of 10501 and groupname of “AllSiteUsersView”already in the acactgrp table.

Listing 2. SQL statements to update access control
insert into acaction (acaction_id, action) values (-5000, 'QuickOrderAutoSuggestionView');
insert into acactactgp (acactgrp_id, acaction_id) values (10501, -5000);
commit;

Step 3: Create a Dojo RefreshArea widget

You need to create a refresh area in the quick order form that is dynamically updated with new content generated by the JSP view page. Listing 4 declares a new refresh controller “QuickOrderAutoSuggestDisplayController” to make an Ajax call to the QuickOrderAutoSuggestionView to populate the refresh area using the response HTML.

Listing 3. Declaration of render context
/**
* Declares a new render context for the AutoSuggest display on Quick Order Page.
*/

wc.render.declareContext("QuickOrderAutoSuggest_Context", null, ""),
Listing 4. Declaration of refresh controller
/** 
* Declares a new refresh controller for Auto Suggest on Quick Order Page
* @PARAM field_id the id of input box user selects
* @Author junmin.liu@us.ibm.com adopted from Commerce FP4 out-of-box code
 */

wc.render.declareRefreshController({
id: "QuickOrderAutoSuggestDisplayController",
renderContext: wc.render.getContextById("QuickOrderAutoSuggest_Context"),
url: "",
formId: "",
field_id: ""
                    
/** 
* Displays the keyword suggestions from the search index
* This function is called when a render context changed event is detected. 
* 
* @param {string} message The render context changed event message
* @param {object} widget The registered refresh area
*/

,renderContextChangedHandler: function(message, widget) {
var controller = this;
var renderContext = this.renderContext;
widget.refresh(renderContext.properties);
}
                    
/** 
* Display the results.
* 
* @param {object} widget The registered refresh area
*/

,postRefreshHandler: function(widget) {
var controller = this;
var renderContext = this.renderContext;
var response = document.getElementById('suggestedKeywordResults');
if(response == null) {
// No response or an error page.   Clear the contents.
document.getElementById("autoSuggestDynamic_Result_div").innerHTML = "";
}
showAutoSuggestIfResults_quickOrder(this.field_id);
}
}),

Step 4: Add new JavaScript functions to the storeCommonUtilities.js

You also need to add several JavaScript functions that are specific to the quick order form. The most important one is to search the local JSON storage and generate an auto-suggest menu.

The following function “doDynamicAutoSuggestFromCache quickOrder” first checks if the previous auto-suggest result contains the searchTerm by looking at the JSON object. It then calls the “createAutoSuggestMenuHTML” function to create the auto-suggest drop-down menu.

Listing 5. Declaration of javascript function to do auto suggest from cache
/**
* search cache stored in web page for suggested SKU list 
* and create HTML snippet for auto-suggest menu
* @Author junmin.liu@us.ibm.com 
*/
                    
function doDynamicAutoSuggestFromCache__quickOrder(url, searchTerm, showHeader, id) {
if(document.getElementById('SKUStorage')){
var skuObject = eval('('+document.getElementById('SKUStorage').innerHTML+')');
var tokens = skuObject[searchTerm.substring(0,DYNAMIC_AUTOSUGGEST_THRESHOLD)];
if(tokens){
var match = false;
var foundTerms = new Array();
for(var j=0; j<tokens.length; j++){
var term = tokens[j];
if(term.indexOf(searchTerm)==0){
foundTerms.push(term);
match = true;
}
}
if(match)
createAutoSuggestMenuHTML(foundTerms);				
else	
document.getElementById('suggestedKeywordResults')=null;
return true;
}
else{
if(searchTerm.length > DYNAMIC_AUTOSUGGEST_THRESHOLD){
document.getElementById('suggestedKeywordResults')=null;	
return true;			  
}
}
}
return false;
}
insert into acaction (acaction_id, action) values (-5000, 'QuickOrderAutoSuggestionView');
insert into acactactgp (acactgrp_id, acaction_id) values (10501, -5000);
commit;

Step 5: Review the implementation result

To verify the results, go to the quick order form of the Madison or Elite starter store. Type in a keyword and verify that for the first character no Ajax call is made to server. When you enter a second character, the Ajax call is made and the auto-suggest menu is displayed.

Figure 2. Quick Order page with Ajax call
The quick order GUI image with Ajax call.

Also, notice that when you enter a third character no Ajax call is made to server, and the auto-suggest menu is displayed only if there are matches to the characters you entered.

Figure 3. Quick Order page without Ajax call
The quick order GUI image without Ajax call.

Conclusion

This article describes the implementation of an auto-suggest menu on a quick order form in the WebSphere Commerce starter store that uses the Solr search capability from WebSphere Commerce V7.2 or above. It leverages the Solr SearchComponent, which is a simple term component that provides fast access to its indexed data. Dojo JavaScript functions are developed to make an Ajax call to the Apache Solr RESTful service API and display a drop-down menu. Also, a flexible and robust browser-side cache solution is implemented to reduce the hits on severs and improve the auto-suggest performance.


Acknowledgements

The author would like to thank his IBM® GBS colleagues Irina Tyshkevich, Kevin Gross, Dave Fehm, and Tom Somboonsong for their review of this article.

Resources

Learn

Get products and technologies

  • Download IBM WebSphere products including WebSphere Transformation Extender Design Studio, version 8.4.0.2 or later.
  • Evaluate IBM products in the way that suits you best: Download a product trial, try a product online, use a product in a cloud environment, or spend a few hours in the SOA Sandbox learning how to implement Service Oriented Architecture efficiently.

Discuss

  • Get involved in the My developerWorks community. Connect with other developerWorks users while exploring the developer-driven blogs, forums, groups, and wikis.

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Commerce on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Commerce, WebSphere
ArticleID=877624
ArticleTitle=Improve the performance of dynamic SKU auto-suggestion
publish-date=04242013