Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@

package org.elasticsearch.script.expression;

import org.elasticsearch.index.fielddata.LeafNumericFieldData;
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
import org.elasticsearch.index.fielddata.LeafNumericFieldData;
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.NumberFieldMapper;
Expand Down Expand Up @@ -64,7 +64,7 @@ public void setUp() throws Exception {
when(fieldData.load(anyObject())).thenReturn(atomicFieldData);

service = new ExpressionScriptEngine();
lookup = new SearchLookup(mapperService, ignored -> fieldData);
lookup = new SearchLookup(mapperService, (ignored, lookup) -> fieldData);
}

private FieldScript.LeafFactory compile(String expression) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@

package org.elasticsearch.script.expression;

import org.elasticsearch.index.fielddata.LeafNumericFieldData;
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
import org.elasticsearch.index.fielddata.LeafNumericFieldData;
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.NumberFieldMapper.NumberFieldType;
Expand Down Expand Up @@ -64,7 +64,7 @@ public void setUp() throws Exception {
when(fieldData.load(anyObject())).thenReturn(atomicFieldData);

service = new ExpressionScriptEngine();
lookup = new SearchLookup(mapperService, ignored -> fieldData);
lookup = new SearchLookup(mapperService, (ignored, lookup) -> fieldData);
}

private NumberSortScript.LeafFactory compile(String expression) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@

package org.elasticsearch.script.expression;

import org.elasticsearch.index.fielddata.LeafNumericFieldData;
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
import org.elasticsearch.index.fielddata.LeafNumericFieldData;
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.NumberFieldMapper.NumberFieldType;
Expand Down Expand Up @@ -64,7 +64,7 @@ public void setUp() throws Exception {
when(fieldData.load(anyObject())).thenReturn(atomicFieldData);

service = new ExpressionScriptEngine();
lookup = new SearchLookup(mapperService, ignored -> fieldData);
lookup = new SearchLookup(mapperService, (ignored, lookup) -> fieldData);
}

private TermsSetQueryScript.LeafFactory compile(String expression) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import org.elasticsearch.painless.spi.Whitelist;
import org.elasticsearch.script.NumberSortScript;
import org.elasticsearch.script.ScriptContext;
import org.elasticsearch.search.lookup.SearchLookup;
import org.elasticsearch.test.ESSingleNodeTestCase;

import java.util.Collections;
Expand All @@ -47,23 +46,21 @@ public void testNeedsScores() {
PainlessScriptEngine service = new PainlessScriptEngine(Settings.EMPTY, contexts);

QueryShardContext shardContext = index.newQueryShardContext(0, null, () -> 0, null);
SearchLookup lookup = new SearchLookup(index.mapperService(), shardContext::getForField);

NumberSortScript.Factory factory = service.compile(null, "1.2", NumberSortScript.CONTEXT, Collections.emptyMap());
NumberSortScript.LeafFactory ss = factory.newFactory(Collections.emptyMap(), lookup);
NumberSortScript.LeafFactory ss = factory.newFactory(Collections.emptyMap(), shardContext.lookup());
assertFalse(ss.needs_score());

factory = service.compile(null, "doc['d'].value", NumberSortScript.CONTEXT, Collections.emptyMap());
ss = factory.newFactory(Collections.emptyMap(), lookup);
ss = factory.newFactory(Collections.emptyMap(), shardContext.lookup());
assertFalse(ss.needs_score());

factory = service.compile(null, "1/_score", NumberSortScript.CONTEXT, Collections.emptyMap());
ss = factory.newFactory(Collections.emptyMap(), lookup);
ss = factory.newFactory(Collections.emptyMap(), shardContext.lookup());
assertTrue(ss.needs_score());

factory = service.compile(null, "doc['d'].value * _score", NumberSortScript.CONTEXT, Collections.emptyMap());
ss = factory.newFactory(Collections.emptyMap(), lookup);
ss = factory.newFactory(Collections.emptyMap(), shardContext.lookup());
assertTrue(ss.needs_score());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.search.lookup.SearchLookup;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

/**
* A {@link FieldMapper} that exposes Lucene's {@link FeatureField}.
Expand Down Expand Up @@ -118,7 +120,7 @@ public Query existsQuery(QueryShardContext context) {
}

@Override
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName, Supplier<SearchLookup> searchLookup) {
throw new IllegalArgumentException("[rank_feature] fields do not support sorting, scripting or aggregating");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@
import org.elasticsearch.common.xcontent.XContentParser.Token;
import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.search.lookup.SearchLookup;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

/**
* A {@link FieldMapper} that exposes Lucene's {@link FeatureField} as a sparse
Expand Down Expand Up @@ -91,7 +93,7 @@ public Query existsQuery(QueryShardContext context) {
}

@Override
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName, Supplier<SearchLookup> searchLookup) {
throw new IllegalArgumentException("[rank_features] fields do not support sorting, scripting or aggregating");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.search.DocValueFormat;
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
import org.elasticsearch.search.lookup.SearchLookup;

import java.io.IOException;
import java.math.BigDecimal;
Expand All @@ -56,6 +57,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

/** A {@link FieldMapper} for scaled floats. Values are internally multiplied
* by a scaling factor and rounded to the closest long. */
Expand Down Expand Up @@ -215,7 +217,7 @@ public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower
}

@Override
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName, Supplier<SearchLookup> searchLookup) {
failIfNoDocValues();
return (cache, breakerService, mapperService) -> {
final IndexNumericFieldData scaledValues = new SortedNumericIndexFieldData.Builder(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,9 @@ public void testFieldData() throws IOException {
// single-valued
ScaledFloatFieldMapper.ScaledFloatFieldType f1
= new ScaledFloatFieldMapper.ScaledFloatFieldType("scaled_float1", scalingFactor);
IndexNumericFieldData fielddata = (IndexNumericFieldData) f1.fielddataBuilder("index").build(null, null, null);
IndexNumericFieldData fielddata = (IndexNumericFieldData) f1.fielddataBuilder("index", () -> {
throw new UnsupportedOperationException();
}).build(null, null, null);
assertEquals(fielddata.getNumericType(), IndexNumericFieldData.NumericType.DOUBLE);
LeafNumericFieldData leafFieldData = fielddata.load(reader.leaves().get(0));
SortedNumericDoubleValues values = leafFieldData.getDoubleValues();
Expand All @@ -161,7 +163,9 @@ public void testFieldData() throws IOException {
// multi-valued
ScaledFloatFieldMapper.ScaledFloatFieldType f2
= new ScaledFloatFieldMapper.ScaledFloatFieldType("scaled_float2", scalingFactor);
fielddata = (IndexNumericFieldData) f2.fielddataBuilder("index").build(null, null, null);
fielddata = (IndexNumericFieldData) f2.fielddataBuilder("index", () -> {
throw new UnsupportedOperationException();
}).build(null, null, null);
leafFieldData = fielddata.load(reader.leaves().get(0));
values = leafFieldData.getDoubleValues();
assertTrue(values.advanceExact(0));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@
import org.elasticsearch.index.mapper.ValueFetcher;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
import org.elasticsearch.search.lookup.SearchLookup;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;

/**
* Simple field mapper hack to ensure that there is a one and only {@link ParentJoinFieldMapper} per mapping.
Expand Down Expand Up @@ -90,7 +92,7 @@ public String typeName() {
}

@Override
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName, Supplier<SearchLookup> searchLookup) {
failIfNoDocValues();
return new SortedSetOrdinalsIndexFieldData.Builder(name(), CoreValuesSourceType.BYTES);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@
import org.elasticsearch.index.mapper.ValueFetcher;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
import org.elasticsearch.search.lookup.SearchLookup;

import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;

/**
* A field mapper used internally by the {@link ParentJoinFieldMapper} to index
Expand Down Expand Up @@ -108,7 +110,7 @@ public String typeName() {
}

@Override
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName, Supplier<SearchLookup> searchLookup) {
failIfNoDocValues();
return new SortedSetOrdinalsIndexFieldData.Builder(name(), CoreValuesSourceType.BYTES);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,21 @@
import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.fielddata.plain.SortedSetOrdinalsIndexFieldData;
import org.elasticsearch.index.mapper.ContentPath;
import org.elasticsearch.index.mapper.MappingLookup;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.MappingLookup;
import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.mapper.SourceValueFetcher;
import org.elasticsearch.index.mapper.StringFieldType;
import org.elasticsearch.index.mapper.TextSearchInfo;
import org.elasticsearch.index.mapper.ValueFetcher;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
import org.elasticsearch.search.lookup.SearchLookup;

import java.io.IOException;
import java.util.ArrayList;
Expand All @@ -58,6 +59,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;

/**
* A {@link FieldMapper} that creates hierarchical joins (parent-join) between documents in the same index.
Expand Down Expand Up @@ -218,7 +220,7 @@ public String typeName() {
}

@Override
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName, Supplier<SearchLookup> searchLookup) {
failIfNoDocValues();
return new SortedSetOrdinalsIndexFieldData.Builder(name(), CoreValuesSourceType.BYTES);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,8 @@ public BitSetProducer bitsetFilter(Query query) {
@Override
@SuppressWarnings("unchecked")
public <IFD extends IndexFieldData<?>> IFD getForField(MappedFieldType fieldType) {
IndexFieldData.Builder builder = fieldType.fielddataBuilder(shardContext.getFullyQualifiedIndex().getName());
IndexFieldData.Builder builder = fieldType.fielddataBuilder(shardContext.getFullyQualifiedIndex().getName(),
shardContext::lookup);
IndexFieldDataCache cache = new IndexFieldDataCache.None();
CircuitBreakerService circuitBreaker = new NoneCircuitBreakerService();
return (IFD) builder.build(cache, circuitBreaker, shardContext.getMapperService());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.search.DocValueFormat;
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
import org.elasticsearch.search.lookup.SearchLookup;

import java.io.IOException;
import java.time.ZoneId;
Expand All @@ -54,6 +55,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;

public class ICUCollationKeywordFieldMapper extends FieldMapper {

Expand Down Expand Up @@ -105,7 +107,7 @@ public Query existsQuery(QueryShardContext context) {
}

@Override
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName, Supplier<SearchLookup> searchLookup) {
failIfNoDocValues();
return new SortedSetOrdinalsIndexFieldData.Builder(name(), CoreValuesSourceType.BYTES);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@
import org.elasticsearch.index.mapper.ValueFetcher;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.query.QueryShardException;
import org.elasticsearch.search.lookup.SearchLookup;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

public class Murmur3FieldMapper extends FieldMapper {

Expand Down Expand Up @@ -105,7 +107,7 @@ public String typeName() {
}

@Override
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName, Supplier<SearchLookup> searchLookup) {
failIfNoDocValues();
return new SortedNumericIndexFieldData.Builder(name(), NumericType.LONG);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,9 @@ public IndexService(
// The sort order is validated right after the merge of the mapping later in the process.
this.indexSortSupplier = () -> indexSettings.getIndexSortConfig().buildIndexSort(
mapperService::fieldType,
indexFieldData::getForField
fieldType -> indexFieldData.getForField(fieldType, indexFieldData.index().getName(), () -> {
throw new UnsupportedOperationException("search lookup not available for index sorting");
})
);
} else {
this.indexSortSupplier = () -> null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ public Sort buildIndexSort(Function<String, MappedFieldType> fieldTypeLookup,
try {
fieldData = fieldDataLookup.apply(ft);
} catch (Exception e) {
throw new IllegalArgumentException("docvalues not found for index sort field:[" + sortSpec.field + "]");
throw new IllegalArgumentException("docvalues not found for index sort field:[" + sortSpec.field + "]", e);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was not strictly required in this PR, though it came natural as I added isRuntimeField to MappedFieldType. and configuring index sorting on runtime fields looked like a bad idea to me.

}
if (fieldData == null) {
throw new IllegalArgumentException("docvalues not found for index sort field:[" + sortSpec.field + "]");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,10 @@ public TerminationHandle warmReader(final IndexShard indexShard, final Elasticse
executor.execute(() -> {
try {
final long start = System.nanoTime();
IndexFieldData.Global<?> ifd = indexFieldDataService.getForField(fieldType);
IndexFieldData.Global<?> ifd = indexFieldDataService.getForField(fieldType, indexFieldDataService.index().getName(),
() -> {
throw new UnsupportedOperationException("search lookup not available when warming an index");
});
IndexFieldData<?> global = ifd.loadGlobal(reader);
if (reader.leaves().isEmpty() == false) {
global.load(reader.leaves().get(0));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.indices.breaker.CircuitBreakerService;
import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCache;
import org.elasticsearch.search.lookup.SearchLookup;

import java.io.Closeable;
import java.io.IOException;
Expand All @@ -38,6 +39,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

public class IndexFieldDataService extends AbstractIndexComponent implements Closeable {
public static final String FIELDDATA_CACHE_VALUE_NODE = "node";
Expand Down Expand Up @@ -106,14 +108,16 @@ public synchronized void clearField(final String fieldName) {
ExceptionsHelper.maybeThrowRuntimeAndSuppress(exceptions);
}

public <IFD extends IndexFieldData<?>> IFD getForField(MappedFieldType fieldType) {
return getForField(fieldType, index().getName());
}

/**
* Returns fielddata for the provided field type, given the provided fully qualified index name, while also making
* a {@link SearchLookup} supplier available that is required for runtime fields.
*/
@SuppressWarnings("unchecked")
public <IFD extends IndexFieldData<?>> IFD getForField(MappedFieldType fieldType, String fullyQualifiedIndexName) {
public <IFD extends IndexFieldData<?>> IFD getForField(MappedFieldType fieldType,
String fullyQualifiedIndexName,
Supplier<SearchLookup> searchLookup) {
final String fieldName = fieldType.name();
IndexFieldData.Builder builder = fieldType.fielddataBuilder(fullyQualifiedIndexName);
IndexFieldData.Builder builder = fieldType.fielddataBuilder(fullyQualifiedIndexName, searchLookup);

IndexFieldDataCache cache;
synchronized (this) {
Expand Down
Loading