Funnelback logo

Documentation

Search session and history

Overview

The Modern UI supports search sessions, the ability to establish a session that persists with the search user across multiple queries. This capability allows Funnelback to record the search and click history for a user, as well as provide a result shopping basket for the user to retain a set of selected search results.

The user session is established through HTTP cookies. History and result selection are saved in a database. There is one database for a given Funnelback installation, but the data is saved on a per-collection basis, meaning that each collection will have separate search & click history, and separate results selection for a given user.

When sessions are enabled, users are automatically assigned a unique ID which is transmitted with every search query.

Caveats

This feature is only supported on Web collections.

Enabling and configuring search sessions

Sessions are enabled with the ui.modern.session=true parameter. Once enabled, Funnelback will immediately start recording searches and clicks, and allow users to select results.

Enabling this parameter will also record unique user IDs in the query and click logs.

Configuration options

Various parameters can be used to configure the session features. Please consult their individual documentation for more details:

Cookies and identifiers

Enabling sessions will provide each user with a unique ID, generated and stored server-side. A J2EE session cookie is then sent back and forth between the user and the server.

It might be desirable in some cases to expose the user ID directly in the cookie, or to enable the user ID generation without enabling the full set of session features. To do so, use the ui.modern.session.set_user_id_cookie setting. When enabled, the user ID will be set in a cookie named user-id, even if ui.modern.session is set to false, and the user ID will also be written in the query and click logs.

Performance impacts

To record search history Funnelback needs to contact the session database for every query and this impacts the query response time. The time spent contacting and querying the database will depend on the server configuration, the type of database used and the size of the database. For example, on a standard Linux server with the built-in database engine and a fresh database the overhead is around 20ms per query.

For this reason it's preferable to not enable the session features until you decide to make use of them in your search results page. If you need unique user IDs only, without the search & click history and results selection, consider using ui.modern.session.set_userid_cookie as described in the previous section. This will cause the Modern UI to generate user IDs, but will not cause it to connect to the database to retrieve the user session data.

Using an external database

Funnelback ships with an embedded H2 database to store the user sessions. If you want to use an external database you need to configure a JNDI datasource in Jetty and initialise a new schema with the required tables.

The following instructions give an overview of the process however some steps will be specific to the external database system type. Please contact support@funnelback.com for further assistance.

The first step is to configure a new datasource in Jetty:

  • Get the relevant JDBC driver JAR for your database
  • Copy SEARCH_HOME/web/conf/funnelback-jndi-datasource.xml.example to SEARCH_HOME/web/conf/funnelback-jndi-datasource.xml
  • Edit the jdbc/search-session definition to configure the JDBC driver for your database. The example given is for PostgreSQL.
  • Edit the jdbc/dialect/search-session to configure the relevant Hibernate Dialect for your database.
  • Edit the Jetty service configuration file SEARCH_HOME/services/jetty-webserver.properties and:
    • Add a new wrapper.app.parameter.X entry pointing to the XML file.
    • Add a new wrapper.java.classpath.X entry pointing to the JDBC driver JAR file.
  • Restart Jetty

You also need to create a new database with the relevant credentials, and initialise its schema with the Funnelback tables. Those steps are specific to the database system type, but Funnelback provides a script to initialise the required tables in SEARCH_HOME/bin/setup/update-session-db.groovy. This script needs to be run with Groovy, specifying SEARCH_HOME/lib/java/all/* in the classpath. For example

 cd $SEARCH_HOME
 tools/groovy/groovy-X.Y.Z/bin/groovy -cp "lib/java/all/*" bin/setup/update-session-db.groovy --help

By default this script will initialise the built-in H2 database. To target your external database you'll have to set the --driver and --url options, to specify the class of the JDBC driver, and the JDBC url to use to connect to the database.

User interface and API

Data model

When search sessions are enabled, a new top-level session node will be present in the Data Model. This node contains:

  • The ID of the user
  • The list of previous queries
  • The list of previously clicked results
  • The selection of results (cart) made by the user

These nodes can be manipulated with FreeMarker like the other nodes of the data model.

REST API

A REST API is available to manipulate the results selection, as well as clearing the search and click history. The cart manipulation is especially useful when you don't want the user to have to submit a new query everytime a result is added or removed from the cart. With this API, the cart operations can be implemented client side in Javascript using Ajax to call the API.

Clearing the search and click history

  • To clear the search history, call /s/search-history.json?collection=... with a HTTP DELETE method.
  • To clear the click history, call /s/click-history.json?collection=... with a HTTP DELETE method.

This will clear the history for the current user.

Cart manipulation

The REST endpoint to manipulate the cart is /s/cart.json?collection=.... The HTTP method used will decide the type of operation:

  • GET will return the cart, as a JSON list.
  • DELETE, when called with no parameters, will clear the entire cart.
  • DELETE, when called with a url parameter (/s/cart.json?collection=...&url=...), will remove the URL from the cart.
  • POST will add a new item to the cart. An url parameter must be present, with the URL of the result to add to the cart.

All method calls will return the content of the cart for the current user, in the form of a JSON list.

Processing and rendering the cart

The result cart can be processed and rendered by implementing a custom Groovy action, and a custom FreeMarker template. Typical use cases includes exporting the cart in a PDF or printable format, or contacting a third party web service to submit the cart information to it.

Processing the cart with a custom Groovy script

The cart will be processed by redirecting the user to /s/cart-process.html?collection=...&profile=.... When this URL is called, Funnelback will invoke the cart-process.groovy script from the collection configuration folder. This script needs to implement the following interface:

 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import com.funnelback.publicui.search.model.collection.Collection;
 import com.funnelback.publicui.search.model.transaction.session.CartResult;
 import com.funnelback.publicui.search.model.transaction.session.SearchUser;
 import com.funnelback.publicui.search.web.controllers.session.CustomCartProcessor;
 import org.springframework.web.servlet.ModelAndView;
 def class MyCartProcessor extends CustomCartProcessor {
   /**
    * Processes the cart
    * 
    * @param collection Collection where processing takes place
    * @param user Current user from the session
    * @param cart Results cart, for the given collection and user
    * @return A {@link ModelAndView} containing the data and the view to use
    */
   @Override
   public ModelAndView process(Collection collection, SearchUser user, List<CartResult> cart) {
     ...
   }
 }

The following parameters are passed in:

collection
A collection object, identical to the one used in User interface hook scripts
user
The current user, with its ID in user.id
cart
The cart content, as a list of results identical to the search data model results in transaction.response.resultPacket.results

The script must return a value of type ModelAndView. This is a composite class containing a data model and the name of a FreeMarker template to use to render the cart. For example, if you wanted to place the current date in the data model, and render the cart using the application-form.ftl template, you could use the following code:

 def model = [:]
 model["date"] = new Date()
 return new ModelAndView("application-form", model);
 

Note that the Modern UI will automatically place the collection, current user and cart content in the data model so you don't need to add them by yourself.

Implementation of this Groovy script is optional. If it's not present, the Modern UI will directly render the cart using the default FreeMarker template name: cart-process.ftl

Rendering the cart with FreeMarker

Once the cart has been processed, the configured FreeMarker template is called with the following entries in the data model:

collection
A collection object, identical to the one used in User interface hook scripts
user
The current user, with its ID in user.id
cart
The cart content, as a list of results identical to the search data model results in transaction.response.resultPacket.results

Other items can be added to the data model by customising the cart processing, as explained in the previous section.

The FreeMarker template is then rendered, identically to a regular search query.

See also

top ⇑