Oracle9iAS Personalization Programmer's Guide Release 2 (v9.0.2) Part Number A95245-02 |
|
This chapter provides examples of REAPI use. In some instances, we provide code snippets; in others, we describe an approach for performing certain kinds of tasks using OP.
OP includes REAPI Demo, a sample program that illustrates the use of many of the REAPI methods. This sample program can be used to learn about REAPI calls and can also used to verify that OP is correctly installed.
After you have installed OP, start REAPI Demo by opening the following URL in Netscape or Internet Explorer:
http://server/redemo/
where server
is the name of the system where Oracle9iAS is installed. The REAPI test site is displayed.
To view the source code for the OP REAPI Demo, click "View Source Code."
For information about how to install and run the demo, see the Oracle9iAS Personalization User's Guide.
The REProxy
methods described in Chapter 4 permit you to instrument your Web site. To use REAPI calls, you must perform the following steps:
REProxy
object.
This section illustrates basic REProxy
usage; for more information about REProxy
and other ways to use it see, "REProxyManager Interaction with JVM" and "Using Multiple Instances of REProxy", later in this chapter.
The following code fragment creates an object named proxy
: You use this object to perform REAPI calls. Note that you must specify the username and password for the RE schema.
final String proxyName = "RE1"; final String dbURL = "jdbc.oracle.thin:@DBServer.myshop.com:1521:DB1"; final String user = "myself"; final String passWd = "secret"; final int cacheSize = 2048; // 2 mbytes final int interval = 10000; // 10 seconds REProxy proxy; ... try { proxy = REProxyManager.createProxy(proxyName, dbURL, user, passWd, cacheSixe, interval); ... } catch (Exception e) { // exception handling here }
After you've created a REProxy
object and gotten an instance of it, you use the proxy to specify REAPI calls, as, for example,
proxy.closeSession();
The sequence of calls depends on whether the application is sessionful or sessionless; see "Sessionful Web Application Outline" or "Sessionless Web Application Outline" later in this chapter for details.
Destroy proxy objects with extreme caution. REProxyRT
objects are shared by many clients; therefore, destruction of a proxy may interrupt recommendation services. The proxy destruction methods must be used very carefully. For Web applications, REProxyRT
objects should be treated as part of the server services; they should not be unless it is absolutely necessary. Like other server components, these objects only need to be destroyed when the server is shut down or taken offline for maintenance purposes.
The following outlines the required steps in the required order for a sessionful Web application (an application that starts a session for each customer).
REProxy
object as described in "Create an REProxy Object", earlier in this chapter. You need to know the user name and password for the RE schema. If the proxy already exists, call getProxy
.
proxy.createCustomerSession(userID, appSessionID); //customer session
proxy.createVisitorSession(userID, appSessionID); //visitor session
idData = IdentificationData.createSessionful(appSessionID);
/*Set input parameters. */ int nRec=10; TuningSettings tune = new TuningSettings(Enum.DataSourec.NAVIGATION, Enum.InterestDimension.NAVIGATION, Enum.PersonalizationIndex.HIGH, Enum.ProfileDataBalance.BALANCED, Enum.ProfileUsage.EXCLUDE); long [] catList = {1, 2, 3, 4}; FilteringSettings filters = new FilteringSettings(); filters.setItemFiltering(1, catList); RecommendationContent rContent = new RecommendationContent ( Enum.Sorting.ASCENDING); /*Get a recommendation. */ try { RecommendationList rList = proxy.recommendTopItems(idData, nRec, tune, filters, rContent); /* Parse the results and pass recommendations to the user*/
proxy.closeSession();
The following outlines the required steps in the required order for a sessionless Web application (an application that does not start a session for each customer). Note that sessionless applications close when they time out.
REProxy
object as described in "Create an REProxy Object", earlier in this chapter. You need to know the user name and password for the RE schema. If the proxy already exists, call getProxy
.
idData = IdentificationData.createSessionless(customerID);
/*Set input parameters.*/ int nRec=10; TuningSettings tune = new TuningSettings(Enum.DataSourec.NAVIGATION, Enum.InterestDimension.NAVIGATION, Enum.PersonalizationIndex.HIGH, Enum.ProfileDataBalance.BALANCED, Enum.ProfileUsage.EXCLUDE); long [] catList = {1, 2, 3, 4}; FilteringSettings filters = new FilteringSettings(); filters.setItemFiltering(1, catList); RecommendationContent rContent = new RecommendationContent ( Enum.Sortinh.ASCENDING); /*Get a recommendation. */ try { RecommendationList rList = proxy.recommendTopItems(idData, nRec, tune, filters, rContent); /* Parse the results and pass recommendations to the user*/
REProxyManager
is a singleton implementation, that is, only one instance of the REProxyManager
class is created in a given JVM instance and the class is automatically loaded in the JVM instance. This behavior has implications about the way your program behaves. The behavior is different depending on whether your application is a standalone Java program or a Java server-side module. The same principle may apply but different usage models for proxy management should be considered
Suppose that you create a standalone Java application using REAPI calls that you execute from the command line with a command such as
java myapplication.class
Such an application has the following characteristics:
REProxyManage
r instance is automatically loaded into the JVM instance.
If you do not destroy the proxy before the program exits, the REProxy
objects remain in memory; they cannot be accessed because the JVM instance that created them no longer exists.
To avoid memory leaks, you must destroy the proxy before the program ends.
If REAPI is called from Java server-side modules, such as servlets or Java Server Pages (JSPs), the REProxyManager
class is loaded on the Oracle9i Application Server where the modules reside.
The Web application that owns and uses the Java modules often starts when the server boots up, and does not close until the server shuts down. In this circumstance, you may create the proxies during the initiation of the Web application or as soon as the first RE request is being processed, but never have to worry about destroying the proxy. As long as the Web application is up and running, the proxy will be used to serve ongoing recommendation requests.
Creation of a proxy is time consuming (a few hundred milliseconds on a Sun E450 server). It is therefore more efficient to never destroy a proxy until the server shuts down, for example, when the system administrator needs to bring the Web application down for maintenance purposes.
If you choose to micro-manage proxies, that is, remove unused proxy objects, you may do so by calling the destroy methods. However, be careful with destroying methods, because both destroy methods will remove proxies forcefully, that is, they do not check to see whether any other process is using the proxy.
REProxyManager
manages a pool of one or more proxies. This section illustrates several ways to use multiple proxies:
The following code fragment illustrates the way you might use two REs to prevent utilization failure. This code assumes that the schema for normal recommendation service is named "RE"; if "RE" fails, you will use a backup RE schema, named "RE_BACKUP".
REProxy initProxy(...) { REProxy proxy; // initialization try { if ((proxy = REProxyManager.getProxy("RE")) == null) proxy = REProxyManager.createProxy("RE", dbURL, username, passWd, cacheSize, interval); } catch (REProxyInitException rie) { proxy = REProxyManager.createProxy("RE_BACKUP", dbURL1, username1, passWd1, cacheSize, interval); } return proxy; }
The following code fragment illustrates the way to guarantee that the recommendation service does not fail when the regular RE server fails. The code implements the class NeverFail
for this purpose.
class NeverFail() { REProxy re1; REProxy re2; void initProxies() { try { if ((re1 = REProxyManager.getProxy("RE1")) == null) String dbURL1="jdbc:oracle:thin:@db1.mycorp.com:1521:orc1"; re1 = REProxyManager.createProxy("RE1", dbURL1, "user1", "pw1", 2048, 10000); if ((re2 = REProxyManager.getProxy("RE2")) == null) String dbURL2="jdbc:oracle:thin:@db2.mycorp.com:1521:orc2"; re2 = REProxyManager.createProxy("RE2", dbURL2, "user2", "pw2", 2048, 10000); } catch (REProxyInitException rie) { // exception handling } } RecommendationList getRecommendation() { RecommendationList rList; // initialize input .... try { rList = re1.recommendTopItems(...); } catch (Exception e) { rList = re2.recommendTopItems(...); return rList; } return rList; } }
The following code fragment illustrates a simple way to do load balancing so that not all customers are handled by the same RE. This example assumes that customers with odd IDs are processed using RE1 and those with even IDs are processed using a different RE, RE2. To accomplish this, first create two different proxies, RE1
and RE2
, and then call getRecommendation()
as follows:
RecommendationList getRecommendation() { RecommendationList rList; // initialize input .... try { if ((idData.getUserID() % 2) == 1) rList = re1.recommendTopItems(...); else rList = re2.recommendTopItems(...); } catch (Exception e) { // exception handling ...... } return rList; }
Use the getAttributes
method of the Recommendation
class rather than attempting to extract the individual recommendations from the array.
OP stores currency data in the demographic table (for example, someone's income) as numbers; that is, OP does not store any kind of label. Both ten dollars (US) and ten pounds sterling (UK) are stored as "10".
There are several ways to ensure that currency data is interpreted correctly; the solution that you pick for your application depends on how your application uses currency data.
This solution allows the country to be taken into account, but it does not closely associate the value with the country.
This solution permits you to compare individual currency values in a meaningful way (10 pounds sterling is more than $10 US) but does not permit you preserve the difference between data such as a salary of $30,000 US in the US, versus the same $30,000 US salary in Brazil. You need such information if, for example, you want to recommend items to highly remunerated individuals in both the US and Brazil; the salary in US dollars of highly remunerated individuals will vary considerably from country to country.
This approach requires that you preprocess the data outside of OP before OP creates recommendations.
This solution would permit you, for example, to determine the highly remunerated individuals for a given country, but it requires that you determine and maintain the bin boundaries appropriately.
This approach requires that you preprocess the data outside of OP before OP creates recommendations.
Oracle9iAS Personalization requires at least one recommendation engine (RE) in at least one recommendation engine farm. In general, you will want to use more than one RE to get satisfactory recommendation performance. Most applications will use multiple REs on different machines and subsequently different database instances. See "Load Balancing" earlier in this chapter for an example of how you might code one of these solutions.
Typically, for a given application, these REs will belong to the same RE farm. If a physical system has multiple processors, and the processors can be leveraged effectively by the database, the number of REs required for a given number of users can be reduced, perhaps even to one. See the administrator's guide for more information.
If your application has more than one RE available for use, it must determine which one to use. Here are three possible solutions:
REProxy
class takes configuration arguments to specify which RE to connect to. The application must determine how to get these configuration arguments, either from an Oracle9iAS/OC4J.properties
file, or by being explicitly coded in the Web applications, or by some other means.
The schema of the MTR_CUSTOMER table consists of 50 generic attributes that can be mapped to any column in the site database. In order to support all different data types, all attributes are of type VARCHAR. Therefore, the mapped columns should be converted to strings. In this release of OP, these mapped columns are treated as categorical or numerical only. If any of the mapped columns is a DATE attribute, it should be converted to a number using the TO_NUMBER function. The converted values can then be binned just like any other attribute by specifying the bin boundaries.
There is binning for demographic data. The attributes that are binned can be of type boolean
. In OP, the bin numbers are represented internally as integers, but the actual values are passed back to the calling applications. That is, the Web application passes in the actual values and gets back actual values.
For certain items, such as airline tickets, the price depends on when the item is purchased. For example, an airline ticket for a Boston to London flight has one price if it purchased 6 months before the date of the flight and a different price if it is purchased two days before the date of the flight.
If the Web application assigns the same item ID to all tickets for the same trip, regardless of when they are purchased, then the items should have different item types, such as "6-month advance", "2-day advance", etc. Alternatively, the application could define taxonomies on the items and get recommendations on the categories.
If the application assigns different item IDs to the same flight purchased at different times (so that a ticket purchased 6 months before the flight has an ID different from a ticket for the same flight purchased 2 days before the flight), all tickets can have the same item type. In this case recommending item IDs may not be appropriate; therefore, the application should define a taxonomy and request recommendations on the categories.
|
Copyright © 2001, 2002 Oracle Corporation. All Rights Reserved. |
|