Skip to content

Commit

Permalink
Add support for source fallback with scaled float field type (elastic…
Browse files Browse the repository at this point in the history
…#89053)

This change adds source fallback support for scaled float. This uses the already existing class 
SourceValueFetcherSortedDoubleIndexFieldData.
  • Loading branch information
jdconrad authored Aug 8, 2022
1 parent 24e367f commit 81265d2
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 9 deletions.
5 changes: 5 additions & 0 deletions docs/changelog/89053.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 89053
summary: Add support for source fallback with scaled float field type
area: Mapping
type: enhancement
issues: []
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ setup:
scaled_float:
type: scaled_float
scaling_factor: 100
scaled_float_no_doc_values:
type: scaled_float
scaling_factor: 100
doc_values: false
token_count:
type: token_count
analyzer: standard
Expand Down Expand Up @@ -105,6 +109,7 @@ setup:
half_float: 3.140625
half_float_no_doc_values: 3.140625
scaled_float: 3.14
scaled_float_no_doc_values: 3.14
token_count: count all these words please

- do:
Expand Down Expand Up @@ -144,6 +149,7 @@ setup:
half_float: [1.123, 2.234]
half_float_no_doc_values: [2.234, 1.123]
scaled_float: [-3.5, 2.5]
scaled_float_no_doc_values: [2.5, -3.5]


- do:
Expand Down Expand Up @@ -2605,6 +2611,58 @@ setup:
source: "doc['scaled_float'].value"
- match: { hits.hits.0.fields.field.0: 3.14 }

---
"scaled_float_no_doc_values":
- do:
catch: bad_request
search:
rest_total_hits_as_int: true
body:
query: { term: { _id: "1" } }
script_fields:
field:
script:
source: "doc['scaled_float_no_doc_values'].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['scaled_float_no_doc_values'].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: "/* avoid stash */ $('scaled_float_no_doc_values', 0.0)"
- match: { hits.hits.0.fields.field.0: 3.14 }
- match: { hits.hits.1.fields.field.0: 0.0 }
- match: { hits.hits.2.fields.field.0: -3.5 }

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

---
"token_count":
- do:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.elasticsearch.index.fielddata.NumericDoubleValues;
import org.elasticsearch.index.fielddata.SortedBinaryDocValues;
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
import org.elasticsearch.index.fielddata.SourceValueFetcherSortedDoubleIndexFieldData;
import org.elasticsearch.index.fielddata.plain.SortedNumericIndexFieldData;
import org.elasticsearch.index.mapper.DocumentParserContext;
import org.elasticsearch.index.mapper.FieldMapper;
Expand All @@ -43,7 +44,9 @@
import org.elasticsearch.script.field.ScaledFloatDocValuesField;
import org.elasticsearch.script.field.ToScriptFieldFactory;
import org.elasticsearch.search.DocValueFormat;
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
import org.elasticsearch.search.lookup.SearchLookup;
import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.xcontent.XContentParser.Token;
Expand All @@ -57,6 +60,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/** A {@link FieldMapper} for scaled floats. Values are internally multiplied
* by a scaling factor and rounded to the closest long. */
Expand Down Expand Up @@ -276,23 +280,49 @@ public Query rangeQuery(

@Override
public IndexFieldData.Builder fielddataBuilder(FieldDataContext fieldDataContext) {
failIfNoDocValues();
return (cache, breakerService) -> {
final IndexNumericFieldData scaledValues = new SortedNumericIndexFieldData.Builder(
FielddataOperation operation = fieldDataContext.fielddataOperation();

if (operation == FielddataOperation.SEARCH) {
failIfNoDocValues();
}

if ((operation == FielddataOperation.SEARCH || operation == FielddataOperation.SCRIPT) && hasDocValues()) {
return (cache, breakerService) -> {
final IndexNumericFieldData scaledValues = new SortedNumericIndexFieldData.Builder(
name(),
IndexNumericFieldData.NumericType.LONG,
(dv, n) -> { throw new UnsupportedOperationException(); }
).build(cache, breakerService);
return new ScaledFloatIndexFieldData(scaledValues, scalingFactor, ScaledFloatDocValuesField::new);
};
}

if (operation == FielddataOperation.SCRIPT) {
SearchLookup searchLookup = fieldDataContext.lookupSupplier().get();
Set<String> sourcePaths = fieldDataContext.sourcePathsLookup().apply(name());

return new SourceValueFetcherSortedDoubleIndexFieldData.Builder(
name(),
IndexNumericFieldData.NumericType.LONG,
(dv, n) -> { throw new UnsupportedOperationException(); }
).build(cache, breakerService);
return new ScaledFloatIndexFieldData(scaledValues, scalingFactor, ScaledFloatDocValuesField::new);
};
CoreValuesSourceType.NUMERIC,
sourceValueFetcher(sourcePaths),
searchLookup.source(),
ScaledFloatDocValuesField::new
);
}

throw new IllegalStateException("unknown field data type [" + operation.name() + "]");
}

@Override
public ValueFetcher valueFetcher(SearchExecutionContext context, String format) {
if (format != null) {
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] doesn't support formats.");
}
return new SourceValueFetcher(name(), context) {
return sourceValueFetcher(context.isSourceEnabled() ? context.sourcePath(name()) : Collections.emptySet());
}

private SourceValueFetcher sourceValueFetcher(Set<String> sourcePaths) {
return new SourceValueFetcher(sourcePaths, nullValue) {
@Override
protected Double parseSourceValue(Object value) {
double doubleValue;
Expand Down

0 comments on commit 81265d2

Please sign in to comment.