OpenSearch/docs/reference/modules/scripting/expression.asciidoc
Robert Muir 7656d7ea73 docs: remove null from expressions case.
Expressions don't have nulls, only doubles. If the field is missing, then its
treated as 0.0. You can query .empty to see if its missing and substitute something else.

See https://github.com/elastic/elasticsearch/pull/18132#discussion_r62068494
2016-05-04 12:50:12 -04:00

121 lines
4.6 KiB
Plaintext

[[modules-scripting-expression]]
=== Lucene Expressions Language
Lucene's expressions compile a `javascript` expression to bytecode. They are
designed for high-performance custom ranking and sorting functions and are
enabled for `inline` and `stored` scripting by default.
[float]
=== Performance
Expressions were designed to have competitive performance with custom Lucene code.
This performance is due to having low per-document overhead as opposed to other
scripting engines: expressions do more "up-front".
This allows for very fast execution, even faster than if you had written a `native` script.
[float]
=== Syntax
Expressions support a subset of javascript syntax: a single expression.
See the link:http://lucene.apache.org/core/6_0_0/expressions/index.html?org/apache/lucene/expressions/js/package-summary.html[expressions module documentation]
for details on what operators and functions are available.
Variables in `expression` scripts are available to access:
* document fields, e.g. `doc['myfield'].value`
* variables and methods that the field supports, e.g. `doc['myfield'].empty`
* Parameters passed into the script, e.g. `mymodifier`
* The current document's score, `_score` (only available when used in a `script_score`)
You can use Expressions scripts for `script_score`, `script_fields`, sort scripts, and numeric aggregation
scripts, simply set the `lang` parameter to `expression`.
[float]
=== Numeric field API
[cols="<,<",options="header",]
|=======================================================================
|Expression |Description
|`doc['field_name'].value` |The value of the field, as a `double`
|`doc['field_name'].empty` |A boolean indicating if the field has no
values within the doc.
|`doc['field_name'].min()` |The minimum value of the field in this document.
|`doc['field_name'].max()` |The maximum value of the field in this document.
|`doc['field_name'].median()` |The median value of the field in this document.
|`doc['field_name'].avg()` |The average of the values in this document.
|`doc['field_name'].sum()` |The sum of the values in this document.
|`doc['field_name'].count()` |The number of values in this document.
|=======================================================================
When a document is missing the field completely, by default the value will be treated as `0`.
You can treat it as another value instead, e.g. `doc['myfield'].empty ? 100 : doc['myfield'].value`
When a document has multiple values for the field, by default the minimum value is returned.
You can choose a different value instead, e.g. `doc['myfield'].sum()`.
When a document is missing the field completely, by default the value will be treated as `0`.
Boolean fields are exposed as numerics, with `true` mapped to `1` and `false` mapped to `0`.
For example: `doc['on_sale'].value ? doc['price'].value * 0.5 : doc['price'].value`
[float]
=== Date field API
Date fields are treated as the number of milliseconds since January 1, 1970 and
support the Numeric Fields API above, with these additional methods:
[cols="<,<",options="header",]
|=======================================================================
|Expression |Description
|`doc['field_name'].getYear()` |Year component, e.g. `1970`.
|`doc['field_name'].getMonth()` |Month component (0-11), e.g. `0` for January.
|`doc['field_name'].getDayOfMonth()` |Day component, e.g. `1` for the first of the month.
|`doc['field_name'].getHourOfDay()` |Hour component (0-23)
|`doc['field_name'].getMinutes()` |Minutes component (0-59)
|`doc['field_name'].getSeconds()` |Seconds component (0-59)
|=======================================================================
The following example shows the difference in years between the `date` fields date0 and date1:
`doc['date1'].getYear() - doc['date0'].getYear()`
[float]
=== `geo_point` field API
[cols="<,<",options="header",]
|=======================================================================
|Expression |Description
|`doc['field_name'].empty` |A boolean indicating if the field has no
values within the doc.
|`doc['field_name'].lat` |The latitude of the geo point.
|`doc['field_name'].lon` |The longitude of the geo point.
|=======================================================================
The following example computes distance in kilometers from Washington, DC:
`haversin(38.9072, 77.0369, doc['field_name'].lat, doc['field_name'].lon)`
In this example the coordinates could have been passed as parameters to the script,
e.g. based on geolocation of the user.
[float]
=== Limitations
There are a few limitations relative to other script languages:
* Only numeric, boolean, date, and geo_point fields may be accessed
* Stored fields are not available