The `top_hits` aggregation should compile scripts only once. (#20738)
Today it compiles when creating the aggregator, meaning that scripts will be compiled as many times as there are buckets. Instead it should compile when creating the factory so that scripts are compiled only once regardless of the number of buckets.
This commit is contained in:
parent
a2e82adc6f
commit
6174e21f47
|
@ -28,6 +28,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
|
|||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.query.QueryParseContext;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptContext;
|
||||
import org.elasticsearch.script.SearchScript;
|
||||
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.AggregationInitializationException;
|
||||
import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
|
||||
|
@ -39,6 +41,7 @@ import org.elasticsearch.search.builder.SearchSourceBuilder;
|
|||
import org.elasticsearch.search.builder.SearchSourceBuilder.ScriptField;
|
||||
import org.elasticsearch.search.fetch.StoredFieldsContext;
|
||||
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
||||
import org.elasticsearch.search.fetch.subphase.ScriptFieldsContext;
|
||||
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
|
||||
import org.elasticsearch.search.sort.ScoreSortBuilder;
|
||||
import org.elasticsearch.search.sort.SortBuilder;
|
||||
|
@ -527,6 +530,18 @@ public class TopHitsAggregationBuilder extends AbstractAggregationBuilder<TopHit
|
|||
@Override
|
||||
protected TopHitsAggregatorFactory doBuild(AggregationContext context, AggregatorFactory<?> parent, Builder subfactoriesBuilder)
|
||||
throws IOException {
|
||||
List<ScriptFieldsContext.ScriptField> scriptFields = null;
|
||||
if (this.scriptFields != null) {
|
||||
scriptFields = new ArrayList<>();
|
||||
for (ScriptField field : this.scriptFields) {
|
||||
SearchScript searchScript = context.searchContext().scriptService().search(
|
||||
context.searchContext().lookup(), field.script(), ScriptContext.Standard.SEARCH, Collections.emptyMap());
|
||||
scriptFields.add(new ScriptFieldsContext.ScriptField(
|
||||
field.fieldName(), searchScript, field.ignoreFailure()));
|
||||
}
|
||||
} else {
|
||||
scriptFields = Collections.emptyList();
|
||||
}
|
||||
return new TopHitsAggregatorFactory(name, type, from, size, explain, version, trackScores, sorts, highlightBuilder,
|
||||
storedFieldsContext, fieldDataFields, scriptFields, fetchSourceContext, context,
|
||||
parent, subfactoriesBuilder, metaData);
|
||||
|
|
|
@ -19,29 +19,25 @@
|
|||
|
||||
package org.elasticsearch.search.aggregations.metrics.tophits;
|
||||
|
||||
import org.elasticsearch.script.ScriptContext;
|
||||
import org.elasticsearch.script.SearchScript;
|
||||
import org.elasticsearch.search.aggregations.Aggregator;
|
||||
import org.elasticsearch.search.aggregations.AggregatorFactories;
|
||||
import org.elasticsearch.search.aggregations.AggregatorFactory;
|
||||
import org.elasticsearch.search.aggregations.InternalAggregation.Type;
|
||||
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
||||
import org.elasticsearch.search.aggregations.support.AggregationContext;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder.ScriptField;
|
||||
import org.elasticsearch.search.fetch.StoredFieldsContext;
|
||||
import org.elasticsearch.search.fetch.subphase.DocValueFieldsContext;
|
||||
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
||||
import org.elasticsearch.search.fetch.subphase.ScriptFieldsContext;
|
||||
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
|
||||
import org.elasticsearch.search.internal.SubSearchContext;
|
||||
import org.elasticsearch.search.sort.SortAndFormats;
|
||||
import org.elasticsearch.search.sort.SortBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class TopHitsAggregatorFactory extends AggregatorFactory<TopHitsAggregatorFactory> {
|
||||
|
||||
|
@ -54,12 +50,12 @@ public class TopHitsAggregatorFactory extends AggregatorFactory<TopHitsAggregato
|
|||
private final HighlightBuilder highlightBuilder;
|
||||
private final StoredFieldsContext storedFieldsContext;
|
||||
private final List<String> docValueFields;
|
||||
private final Set<ScriptField> scriptFields;
|
||||
private final List<ScriptFieldsContext.ScriptField> scriptFields;
|
||||
private final FetchSourceContext fetchSourceContext;
|
||||
|
||||
public TopHitsAggregatorFactory(String name, Type type, int from, int size, boolean explain, boolean version, boolean trackScores,
|
||||
List<SortBuilder<?>> sorts, HighlightBuilder highlightBuilder, StoredFieldsContext storedFieldsContext,
|
||||
List<String> docValueFields, Set<ScriptField> scriptFields, FetchSourceContext fetchSourceContext,
|
||||
List<String> docValueFields, List<ScriptFieldsContext.ScriptField> scriptFields, FetchSourceContext fetchSourceContext,
|
||||
AggregationContext context, AggregatorFactory<?> parent, AggregatorFactories.Builder subFactories,
|
||||
Map<String, Object> metaData) throws IOException {
|
||||
super(name, type, context, parent, subFactories, metaData);
|
||||
|
@ -98,13 +94,8 @@ public class TopHitsAggregatorFactory extends AggregatorFactory<TopHitsAggregato
|
|||
if (docValueFields != null) {
|
||||
subSearchContext.docValueFieldsContext(new DocValueFieldsContext(docValueFields));
|
||||
}
|
||||
if (scriptFields != null) {
|
||||
for (ScriptField field : scriptFields) {
|
||||
SearchScript searchScript = subSearchContext.scriptService().search(subSearchContext.lookup(), field.script(),
|
||||
ScriptContext.Standard.SEARCH, Collections.emptyMap());
|
||||
subSearchContext.scriptFields().add(new org.elasticsearch.search.fetch.subphase.ScriptFieldsContext.ScriptField(
|
||||
field.fieldName(), searchScript, field.ignoreFailure()));
|
||||
}
|
||||
for (ScriptFieldsContext.ScriptField field : scriptFields) {
|
||||
subSearchContext.scriptFields().add(field);
|
||||
}
|
||||
if (fetchSourceContext != null) {
|
||||
subSearchContext.fetchSourceContext(fetchSourceContext);
|
||||
|
|
Loading…
Reference in New Issue