Scripting
The scripting functionality enables you to use scripts to evaluate custom expressions. For example, you could use a script to return “script fields” as part of a search request or evaluate a custom score for a query.
The scripting language currently supported is ChaiScript.
For example, the following script is used while adding/updating a given document to increment a “serial” number field:
PUT /twitter/user/John
{
"_script": "_doc.serial = _old_doc.serial + 1"
}
The above example initializes the first serial number of the document to 1 and increments the counter by one thereafter.
Dot Access Notation
When accessing document objects in the scripts, you can either use dot access
notation as exemplified above (i.e. _doc.serial
) or array call notation
(i.e. _doc["serial"]
).
How to Use Scripts
Wherever scripting is supported in the Xapiand API, the structure for scripts follows the same patterns:
"_script" {
"_type": "script",
"_chai": {
( "_name": "<script_name>", )?
( "_body": "<script_body>", )?
( "_params": <params>, )?
}
}
Or, for short:
"_script": "<script_name|script_body>"
Script Caching
All scripts are cached so that they only need to be recompiled when updates occur. By default, the cache size is 100 and scripts do not have a time-based expiration.
Prefer Parameters
The first time Xapiand sees a new script, it compiles it and stores the compiled
version in a cache. Compilation can be a heavy process, so try using
Foreign Scripts and Variables.
Variables
Xapiand adds a few default variables to the running script context:
Variable | Description |
---|---|
_doc |
Current document. |
_old_doc |
Old document (in case of updates / deletes). |
_method |
HTTP method that triggered the script. |
If you need to pass additional variables into the script, you should pass them in as named parameters instead of hard-coding values into the script itself. For example, if you want to be able to multiply a field value by different multipliers, don’t hard-code the multiplier into the script:
PUT /twitter/user/John
{
"multiplied_field": 7,
"_script": {
"_type": "script",
"_value": "_doc.multiplied_field *= 2"
}
}
Instead, pass it in as a named parameter:
PUT /twitter/user/John
{
"multiplied_field": 7,
"_script": {
"_type": "script",
"_value": "_doc.multiplied_field *= multiplier",
"_params": {
"multiplier": 2
}
}
}
The first version has to be recompiled every time the multiplier changes. The second version is only compiled once.
Foreign Scripts
Scripts can also be loaded from a different database / document. These are called foreign scripts. To use foreign script, first you need to create a document containing the script:
PUT /path/to/my_scripts/multiplier
{
"_recurse": false,
"script": {
"_chai": {
"_body": "_doc.multiplied_field *= multiplier",
"_params": {
"multiplier": 1
}
}
}
}
We’re placing the script inside the "script"
field, but we also use
"_recurse": false
so "script"
doesn’t get recursed and analyzed as a regular
field by the Schema.
We then can use the foreign script by specifying the _foreign
(i.e. the full
index path, the document ID and the selector). In the example, the index is
path/to/my_scripts
, the document ID is multiplier
and the selector is a
Drill Selector that
gets the "script"
field:
PUT /twitter/user/John
{
"multiplied_field": 7,
"_script": {
"_type": "foreign/object",
"_foreign": "path/to/my_scripts/multiplier.script",
"_params": {
"multiplier": 3
}
}
}