Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add text field support in the Painless scripting fields API #89396

Merged
merged 3 commits into from
Aug 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/changelog/89396.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 89396
summary: Add text field support in the Painless scripting fields API
area: Mapping
type: enhancement
issues: []
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ setup:
type: scaled_float
scaling_factor: 100
doc_values: false
text:
type: text
fielddata: true
text_no_field_data:
type: text
token_count:
type: token_count
analyzer: standard
Expand Down Expand Up @@ -110,6 +115,8 @@ setup:
half_float_no_doc_values: 3.140625
scaled_float: 3.14
scaled_float_no_doc_values: 3.14
text: "Lots of text."
text_no_field_data: "Lots of text."
token_count: count all these words please

- do:
Expand Down Expand Up @@ -150,6 +157,8 @@ setup:
half_float_no_doc_values: [2.234, 1.123]
scaled_float: [-3.5, 2.5]
scaled_float_no_doc_values: [2.5, -3.5]
text: ["Lots of text.", "even more text", "SOOOOO much text"]
text_no_field_data: ["Lots of text.", "even more text", "SOOOOO much text"]


- do:
Expand Down Expand Up @@ -2719,6 +2728,264 @@ setup:
source: "int value = field('dne').get(1, 1); value"
- match: { hits.hits.0.fields.field.0: 1 }

---
"text":
- do:
search:
rest_total_hits_as_int: true
body:
query: { term: { _id: "1" } }
script_fields:
field:
script:
source: "doc['text'].get(0)"
- match: { hits.hits.0.fields.field.0: lots }

- do:
search:
rest_total_hits_as_int: true
body:
query: { term: { _id: "1" } }
script_fields:
field:
script:
source: "doc['text'].value"
- match: { hits.hits.0.fields.field.0: lots }

- do:
search:
rest_total_hits_as_int: true
body:
sort: [ { rank: asc } ]
script_fields:
field:
script:
source: "field('text').get('')"
- match: { hits.hits.0.fields.field.0: "Lots of text." }
- match: { hits.hits.1.fields.field.0: "" }
- match: { hits.hits.2.fields.field.0: "Lots of text." }

- do:
search:
rest_total_hits_as_int: true
body:
sort: [ { rank: asc } ]
script_fields:
field:
script:
source: "/* avoid yaml stash */ $('text', '')"
- match: { hits.hits.0.fields.field.0: "Lots of text." }
- match: { hits.hits.1.fields.field.0: "" }
- match: { hits.hits.2.fields.field.0: "Lots of text." }

- do:
search:
rest_total_hits_as_int: true
body:
sort: [ { rank: asc } ]
script_fields:
field:
script:
source: "String defaultText = 'default text'; field('text').get(defaultText)"
- match: { hits.hits.0.fields.field.0: "Lots of text." }
- match: { hits.hits.1.fields.field.0: "default text" }
- match: { hits.hits.2.fields.field.0: "Lots of text." }

- do:
search:
rest_total_hits_as_int: true
body:
sort: [ { rank: asc } ]
script_fields:
field:
script:
source: "String defaultText = 'default text'; $('text', defaultText)"
- match: { hits.hits.0.fields.field.0: "Lots of text." }
- match: { hits.hits.1.fields.field.0: "default text" }
- match: { hits.hits.2.fields.field.0: "Lots of text." }

- do:
search:
rest_total_hits_as_int: true
body:
sort: [ { rank: asc } ]
script_fields:
field:
script:
source: "field('text').get(1, '')"
- match: { hits.hits.0.fields.field.0: "" }
- match: { hits.hits.1.fields.field.0: "" }
- match: { hits.hits.2.fields.field.0: "SOOOOO much text" }

- do:
search:
rest_total_hits_as_int: true
body:
sort: [ { rank: asc } ]
script_fields:
field:
script:
source: "String defaultText = 'default text'; field('text').get(1, defaultText)"
- match: { hits.hits.0.fields.field.0: "default text" }
- match: { hits.hits.1.fields.field.0: "default text" }
- match: { hits.hits.2.fields.field.0: "SOOOOO much text" }

- do:
search:
rest_total_hits_as_int: true
body:
sort: [ { rank: asc } ]
script_fields:
field:
script:
source: "field('text').get(1, '')"
- match: { hits.hits.0.fields.field.0: "" }
- match: { hits.hits.1.fields.field.0: "" }
- match: { hits.hits.2.fields.field.0: "SOOOOO much text" }

- do:
search:
rest_total_hits_as_int: true
body:
sort: [ { rank: asc } ]
script_fields:
field:
script:
source: "String cat = ''; for (String s : field('text')) { cat += s; } cat + field('text').size();"
- match: { hits.hits.0.fields.field.0: "Lots of text.1" }
- match: { hits.hits.1.fields.field.0: "0" }
- match: { hits.hits.2.fields.field.0: "Lots of text.SOOOOO much texteven more text3" }

---
"text_no_field_data":
- do:
catch: bad_request
search:
rest_total_hits_as_int: true
body:
query: { term: { _id: "1" } }
script_fields:
field:
script:
source: "doc['text_no_field_data'].get(0)"
- match: { error.failed_shards.0.reason.caused_by.type: "illegal_argument_exception" }

- do:
catch: bad_request
search:
rest_total_hits_as_int: true
body:
query: { term: { _id: "1" } }
script_fields:
field:
script:
source: "doc['text_no_field_data'].value"
- match: { error.failed_shards.0.reason.caused_by.type: "illegal_argument_exception" }

- do:
search:
rest_total_hits_as_int: true
body:
sort: [ { rank: asc } ]
script_fields:
field:
script:
source: "field('text_no_field_data').get('')"
- match: { hits.hits.0.fields.field.0: "Lots of text." }
- match: { hits.hits.1.fields.field.0: "" }
- match: { hits.hits.2.fields.field.0: "Lots of text." }

- do:
search:
rest_total_hits_as_int: true
body:
sort: [ { rank: asc } ]
script_fields:
field:
script:
source: "/* avoid yaml stash */ $('text_no_field_data', '')"
- match: { hits.hits.0.fields.field.0: "Lots of text." }
- match: { hits.hits.1.fields.field.0: "" }
- match: { hits.hits.2.fields.field.0: "Lots of text." }

- do:
search:
rest_total_hits_as_int: true
body:
sort: [ { rank: asc } ]
script_fields:
field:
script:
source: "String defaultText = 'default text'; field('text_no_field_data').get(defaultText)"
- match: { hits.hits.0.fields.field.0: "Lots of text." }
- match: { hits.hits.1.fields.field.0: "default text" }
- match: { hits.hits.2.fields.field.0: "Lots of text." }

- do:
search:
rest_total_hits_as_int: true
body:
sort: [ { rank: asc } ]
script_fields:
field:
script:
source: "String defaultText = 'default text'; $('text_no_field_data', defaultText)"
- match: { hits.hits.0.fields.field.0: "Lots of text." }
- match: { hits.hits.1.fields.field.0: "default text" }
- match: { hits.hits.2.fields.field.0: "Lots of text." }

- do:
search:
rest_total_hits_as_int: true
body:
sort: [ { rank: asc } ]
script_fields:
field:
script:
source: "field('text_no_field_data').get(1, '')"
- match: { hits.hits.0.fields.field.0: "" }
- match: { hits.hits.1.fields.field.0: "" }
- match: { hits.hits.2.fields.field.0: "SOOOOO much text" }

- do:
search:
rest_total_hits_as_int: true
body:
sort: [ { rank: asc } ]
script_fields:
field:
script:
source: "String defaultText = 'default text'; field('text_no_field_data').get(1, defaultText)"
- match: { hits.hits.0.fields.field.0: "default text" }
- match: { hits.hits.1.fields.field.0: "default text" }
- match: { hits.hits.2.fields.field.0: "SOOOOO much text" }

- do:
search:
rest_total_hits_as_int: true
body:
sort: [ { rank: asc } ]
script_fields:
field:
script:
source: "field('text_no_field_data').get(1, '')"
- match: { hits.hits.0.fields.field.0: "" }
- match: { hits.hits.1.fields.field.0: "" }
- match: { hits.hits.2.fields.field.0: "SOOOOO much text" }

- do:
search:
rest_total_hits_as_int: true
body:
sort: [ { rank: asc } ]
script_fields:
field:
script:
source: "String cat = ''; for (String s : field('text_no_field_data')) { cat += s; } cat + field('text_no_field_data').size();"
- match: { hits.hits.0.fields.field.0: "Lots of text.1" }
- match: { hits.hits.1.fields.field.0: "0" }
- match: { hits.hits.2.fields.field.0: "Lots of text.SOOOOO much texteven more text3" }

---
"version and sequence number":
- do:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ public static class SourceValueFetcherSortedBinaryDocValues extends SortedBinary
private final ValueFetcher valueFetcher;
private final SourceLookup sourceLookup;

private SortedSet<Object> values;
private Iterator<Object> iterator;
private final SortedSet<BytesRef> values;
private Iterator<BytesRef> iterator;

public SourceValueFetcherSortedBinaryDocValues(
LeafReaderContext leafReaderContext,
Expand All @@ -102,12 +102,19 @@ public SourceValueFetcherSortedBinaryDocValues(
this.leafReaderContext = leafReaderContext;
this.valueFetcher = valueFetcher;
this.sourceLookup = sourceLookup;

values = new TreeSet<>();
}

@Override
public boolean advanceExact(int doc) throws IOException {
sourceLookup.setSegmentAndDocument(leafReaderContext, doc);
values = new TreeSet<>(valueFetcher.fetchValues(sourceLookup, Collections.emptyList()));
values.clear();

for (Object object : valueFetcher.fetchValues(sourceLookup, Collections.emptyList())) {
values.add(new BytesRef(object.toString()));
}

iterator = values.iterator();

return true;
Expand All @@ -121,7 +128,7 @@ public int docValueCount() {
@Override
public BytesRef nextValue() throws IOException {
assert iterator.hasNext();
return new BytesRef(iterator.next().toString());
return iterator.next();
}
}
}
Loading