Storing custom data within the data model

This article describes how to add custom data to the data model using a hook script. Once the custom values are in the data model they can be accessed from a Freemarker template or other search lifecycle plugins.

Custom data elements in the data model

If you need to store variables within the data model there are several customData maps that exist for this purpose:

  • transaction.question.customData[]: Custom data to attach to the search question. Values can be added in the preProcess() or preDatafetch() methods of a search lifecycle plugin

  • transaction.response.customData[]: Custom data to attach to the search response. Values can be added in the postProcess() or postDatafetch() methods of a search lifecycle plugin.

  • transaction.response.results[n].customData[]: Result-specific custom data. Per result values can be added in the postProcess() or postDatafetch() method of a search lifecycle plugin

  • transaction.customData[]: Global custom data.

    Global custom data not currently accessible from Freemarker so only use this element if you are accessing the search results JSON directly.

Why custom data?

The main uses of custom data elements within the data model are to store additional fields generated from within a plugin that are either:

  • exposed in the search results JSON to be used in your search results template,

  • read by a downstream plugin for further processing.

Adding custom data

The following example shows how to set a few different types of variables in a post process hook script and write these to the transaction.question.customData[] list in the data model:

Search lifecycle plugin
@Override
public void preProcess(SearchLifeCycleContext searchLifeCycleContext, SearchTransaction transaction) {

    // Define some variables of different types
    Integer number = 3;
    String string = "Example string";
    HashMap<String,String> map = new HashMap<>()
    map.put("key1","val1");
    map.put("key2","val2");
    String[] list=["item","another item"]

    // Add these to custom data in the data model's search question
    transaction.getQuestion().getCustomData().put("number",number);
    transaction.getQuestion().getCustomData().put("string",string);
    transaction.getQuestion().getCustomData().put("list",list);
    transaction.getQuestion().getCustomData().put("map",map);
}

This results in a data model structure like the following.

Some data model elements have been collapsed for clarity in the example.
search.json
{
	"question": { ... },
	"extraSearchesTerminated": false,
	"response": {
		"resultPacket": { ... },
		"returnCode": 0,
		"untruncatedPadreOutputSize": 11906,
		"facets": [ ... ],
		"customData": {
			"number": 3,
			"string": "This is a string value",
			"list": [
				"item",
				"another item"
				],
			"map": {
				"key1": "val1",
				"key2": "val2"
				}
		},
		"optimiserModel": null,
		"curator": { ... },
		"performanceMetrics": { ... }
	},
	"session": { ... },
	"QueryString": "collection=example&query=!showall",
	"error": null
}