Tutorial #017: Using Groovy scripts to calculate document fields on the fly!

Sometimes it is important to calculate a derivative field when the author changes something in the document. Derived fields often help inform more complex requirements for queries you might be executing on your documents.

An example of this could be: looking to parent nodes to retrieve the name of the category a document is in. 

Or perhaps when you're building a webshop, it could be useful to calculate the average rating of a product based on reviews attached to the product. 

The out of the box implementation of the Derived fields is quite limited and quickly starts requiring the implementation of custom classes. Part of what XIN Mods tries to achieve is to significantly reduce the amount of customisation you have to do to a vanilla Bloomreach instance to get it to do what you need it to.

Let's get in to it! 

To keep with the recipes example we have been working on we will be implementing a groovy script derivative field that stores the number of ingredients a recipe has, so that in the future we might be able to create a simple recipe filter that allows the user to select recipes by the number of ingredients they require. 

Code #1

The simple implementation that will log a simple message when the DeriveFunction kicks off.

									
									import nz.xinsolutions.derived.DeriveFunction
									import org.apache.jackrabbit.value.*;
									
									class IngredientCountDeriveFunction implements DeriveFunction {
									
									
									    boolean derive(Session jcrSession, Node document) {
									        println "determine ingredient count";
									        return true
									
									    }
									
									}

 

Code #2

A proper implementation that determines the number of ingredients and stores the value in a field called "xinmods:nIngredients".

 

									import nz.xinsolutions.derived.DeriveFunction
									import org.apache.jackrabbit.value.*;
									
									class IngredientCountDeriveFunction implements DeriveFunction {
									
									
									    boolean derive(Session jcrSession, Node document) {
									        println "determine ingredient count"
									        def iterator = document.getNodes("xinmods:ingredient")
									        long count = 0
									            
									        while (iterator.hasNext()) {
									            ++count;
									            iterator.next();
									        }
									
									        println "found ${count} ingredients"
									
									        document.setProperty("xinmods:nIngredients", count);
									        return true
									
									    }
									
									}
									

 

 

Also Read