A script is executable logic placed in an Elasticsearch request to compute a value or change a document. It can read document data, make conditional decisions, and apply several changes in one request. For document updates, the script source commonly uses ctx._source to access fields in the stored source. section 5.4.3
Use scripts when a direct field replacement is not enough: append or remove an array value, add or remove fields, set multiple values, or derive a flag from a business rule. Keep variable inputs in params rather than embedding changing values in the script logic. section 5.4.3
Flag a movie from a threshold
A movie can be marked blockbuster only when its box-office value exceeds a supplied threshold. The script reads boxoffice_gross_in_millions, compares it with params.gross_earnings_threshold, and writes either true or false to blockbuster. This keeps the rule in the script while allowing the threshold to vary per request. section 5.4.3
Listing 5.29 Dynamically passing a parameter to the script
POST movies/_update/1 { "script": { #1 "source": """ #2 if(ctx._source.boxoffice_gross_in_millions > params.gross_earnings_threshold) {ctx._source.blockbuster = true} else {ctx._source.blockbuster = false} """, "params": { #3 "gross_earnings_threshold":150 } } } #1 Business logic goes here. #2 Checks the value against params #3 Provides the parameter values
This request separates the decision rule in source from the changing gross-earnings threshold in params. section 5.4.3
Scripts also work across all documents selected by a query. With _update_by_query, Elasticsearch finds matching documents and runs the script for each one; each successful change is re-indexed. Individual failures are logged while other matched documents continue, and version conflicts can be retried or ignored through configured settings. section 5.4.7
Rename an actor everywhere it appears
An _update_by_query request can match movies containing Al Pacino, add Oscar Winner Al Pacino to each actors array, and remove the old value. The query chooses the documents; the script performs the transformation. section 5.4.7
Listing 5.34 Updating a document using a query method
POST movies/_update_by_query #1
{
"query": { #2
"match": {
"actors": "Al Pacino"
}
},
"script": { #3
"source": """
ctx._source.actors.add('Oscar Winner Al Pacino');
ctx._source.actors.remove(ctx._source.actors.indexOf('Al Pacino'))
""",
"lang": "painless"
}
}
The listing combines a match query with a Painless script that adds the replacement actor name and removes the old one. section 5.4.7
A script need not persist a change. Search requests can define scripted fields that compute an ad hoc response field, such as top_rated_movie from rating, while script_score can calculate a custom relevance score from document fields, the original score, and parameters. For simple field-based scoring needs, field_value_factor is an alternative to a more complex script. section 8.8.5 section 11.7.2
Listing 11.28 Multiplying the field’s value by an external parameter
GET products/_search
{
"query": {
"function_score": {
"query": {
"term": {
"product": "tv"
}
},
"script_score": { #1
"script": { #B #2
"source":"_score * doc['user_ratings'].value * params['factor']", #3
"params": { #4
"factor":3
}
}
}
}
}
}
The script_score example multiplies the original score by a product rating and an external factor parameter. section 11.7.2
Scripts can also participate in an upsert. If the targeted document exists, the script updates it; if it does not, the upsert object supplies the new document instead. This lets one request handle both an initial insert and later scripted updates. section 5.4.5
