Skip to content

Commit

Permalink
[7.x] Update Painless Fields API design to use mapped types (#78950) (#…
Browse files Browse the repository at this point in the history
…79201)

This change updates the Painless fields API to use mapped types instead of Java types. For this initial 
release we only support unsigned long field.

As we now intend to do conversions solely on the field classes themselves, converters and field values 
have been removed. Instead of using field values potentially as source fallback we will now rely on 
whatever class is passed into the script to support the field method. In the future, this method will 
need to check if a field exists on doc and if not, then do source fallback itself once that feature is 
supported.

The path to retrieve a field is also different. Instead of using script doc values we now have our own 
way to retrieve the fields with a getScriptField method added to LeafDocLookup. This allows us less 
restrictive design space to generate the field type based the type in the leaf doc lookup; however, this 
will still require additional information that we need to plumb through for certain field types. Once we 
support all the field types this makes it easier to deprecate and remove script doc values.
  • Loading branch information
jdconrad committed Oct 18, 2021
1 parent 332a8d6 commit bbd48ee
Show file tree
Hide file tree
Showing 48 changed files with 324 additions and 3,050 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,13 @@
# The whitelist for the fields api

# API
class org.elasticsearch.script.field.Field {
org.elasticsearch.script.field.Converter BigInteger @augmented[augmented_canonical_class_name="org.elasticsearch.script.field.BigIntegerField"]
org.elasticsearch.script.field.Converter Long @augmented[augmented_canonical_class_name="org.elasticsearch.script.field.LongField"]
class org.elasticsearch.script.field.Field @dynamic_type {
String getName()
boolean isEmpty()
int size()
List getValues()
def getValue(def)
double getDouble(double)
long getLong(long)
org.elasticsearch.script.field.Field as(org.elasticsearch.script.field.Converter)
}

class org.elasticsearch.script.field.Converter {
def getValue(int, def)
}

class org.elasticsearch.script.DocBasedScript {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,24 +66,6 @@ setup:
- is_false: aggregations.str_terms.buckets.1.key_as_string
- match: { aggregations.str_terms.buckets.1.doc_count: 1 }

---
"String Value Script with doc notation (fields api)":

- do:
search:
rest_total_hits_as_int: true
body: { "size" : 0, "aggs" : { "str_terms" : { "terms" : { "field" : "str", "script": { "source": "return field('str').getValue('') + \"1\""} } } } }

- match: { hits.total: 3 }

- length: { aggregations.str_terms.buckets: 2 }
- match: { aggregations.str_terms.buckets.0.key: "abc1" }
- is_false: aggregations.str_terms.buckets.0.key_as_string
- match: { aggregations.str_terms.buckets.0.doc_count: 2 }
- match: { aggregations.str_terms.buckets.1.key: "bcd1" }
- is_false: aggregations.str_terms.buckets.1.key_as_string
- match: { aggregations.str_terms.buckets.1.doc_count: 1 }

---
"Long Value Script with doc notation":

Expand All @@ -102,24 +84,6 @@ setup:
- is_false: aggregations.long_terms.buckets.1.key_as_string
- match: { aggregations.long_terms.buckets.1.doc_count: 1 }

---
"Long Value Script with doc notation (fields api)":

- do:
search:
rest_total_hits_as_int: true
body: { "size" : 0, "aggs" : { "long_terms" : { "terms" : { "field" : "number", "script": { "source": "return field('number').getValue(0L) + 1"} } } } }

- match: { hits.total: 3 }

- length: { aggregations.long_terms.buckets: 2 }
- match: { aggregations.long_terms.buckets.0.key: 2.0 }
- is_false: aggregations.long_terms.buckets.0.key_as_string
- match: { aggregations.long_terms.buckets.0.doc_count: 2 }
- match: { aggregations.long_terms.buckets.1.key: 3.0 }
- is_false: aggregations.long_terms.buckets.1.key_as_string
- match: { aggregations.long_terms.buckets.1.doc_count: 1 }

---
"Double Value Script with doc notation":

Expand All @@ -138,24 +102,6 @@ setup:
- is_false: aggregations.double_terms.buckets.1.key_as_string
- match: { aggregations.double_terms.buckets.1.doc_count: 1 }

---
"Double Value Script with doc notation (fields api)":

- do:
search:
rest_total_hits_as_int: true
body: { "size" : 0, "aggs" : { "double_terms" : { "terms" : { "field" : "double", "script": { "source": "return field('double').getValue(0.0) + 1"} } } } }

- match: { hits.total: 3 }

- length: { aggregations.double_terms.buckets: 2 }
- match: { aggregations.double_terms.buckets.0.key: 2.0 }
- is_false: aggregations.double_terms.buckets.0.key_as_string
- match: { aggregations.double_terms.buckets.0.doc_count: 2 }
- match: { aggregations.double_terms.buckets.1.key: 3.0 }
- is_false: aggregations.double_terms.buckets.1.key_as_string
- match: { aggregations.double_terms.buckets.1.doc_count: 1 }

---
"Bucket script with keys":

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,3 @@ setup:
- match: { hits.total: 3 }
- match: { aggregations.total.value: 4.0 }

---
"Scripted Metric Agg Total (fields api)":

- do:
search:
rest_total_hits_as_int: true
body: {
"size": 0,
"aggs": {
"total": {
"scripted_metric": {
"init_script": "state.transactions = []",
"map_script": "state.transactions.add(field('double').getValue(0.0))",
"combine_script": "double total = 0.0; for (t in state.transactions) { total += t } return total",
"reduce_script": "double total = 0; for (a in states) { total += a } return total"
}
}
}
}

- match: { hits.total: 3 }
- match: { aggregations.total.value: 4.0 }
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,6 @@ setup:

- match: { hits.hits.0.fields.bar.0: "aaabbb"}

---
"Scripted Field (fields api)":
- do:
search:
rest_total_hits_as_int: true
body:
script_fields:
bar:
script:
source: "field('foo').getValue('') + params.x;"
params:
x: "bbb"

- match: { hits.hits.0.fields.bar.0: "aaabbb"}

---
"Scripted Field Doing Compare":
- do:
Expand Down Expand Up @@ -88,35 +73,6 @@ setup:

- match: { hits.hits.0.fields.bar.0: false}

---
"Scripted Field Doing Compare (fields api)":
- do:
search:
rest_total_hits_as_int: true
body:
script_fields:
bar:
script:
source: "boolean compare(Supplier s, def v) {return s.get() == v;}
compare(() -> { return field('foo').getValue('') }, params.x);"
params:
x: "aaa"

- match: { hits.hits.0.fields.bar.0: true}
- do:
search:
rest_total_hits_as_int: true
body:
script_fields:
bar:
script:
source: "boolean compare(Supplier s, def v) {return s.get() == v;}
compare(() -> { return doc['foo'].value }, params.x);"
params:
x: "bbb"

- match: { hits.hits.0.fields.bar.0: false}

---
"Scripted Field with a null safe dereference (non-null)":
- do:
Expand Down Expand Up @@ -160,19 +116,6 @@ setup:

- match: { hits.hits.0.fields.bar.0: 7}

---
"Access a date (fields api)":
- do:
search:
rest_total_hits_as_int: true
body:
script_fields:
bar:
script:
source: "field('date').getValue(new Date()).dayOfWeekEnum.value"

- match: { hits.hits.0.fields.bar.0: 7}

---
"Access many dates":
- do:
Expand All @@ -191,24 +134,6 @@ setup:
- match: { hits.hits.0.fields.bar.0: "7 3 3"}

---
"Access many dates (fields api)":
- do:
search:
rest_total_hits_as_int: true
body:
script_fields:
bar:
script:
source: >
StringBuilder b = new StringBuilder();
for (def date : field('dates').getValues()) {
b.append(" ").append(date.getDayOfWeekEnum().value);
}
return b.toString().trim()
- match: { hits.hits.0.fields.bar.0: "7 3 3"}

---
"Scripted Field with script error":
- do:
Expand Down

0 comments on commit bbd48ee

Please sign in to comment.