Skip to content

Commit f65029d

Browse files
authored
[ML] Add new inference_rescorer via ML plugin (#96960)
This is a first step in supporting models as a rescoring mechanism for second-stage retrieval. This commit adds: - a new feature flag behind which this feature will reside until its feature complete - The ability to use a GBDT regression model (this will ultimately be changed to a new "ltr" or "search" model type I would think) as a rescorer - Extract indexed document fields to pass to the rescorer (this is only the first set of feature extractions planned to add)
1 parent e4df571 commit f65029d

File tree

18 files changed

+1237
-4
lines changed

18 files changed

+1237
-4
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
package org.elasticsearch.index.query;
9+
10+
import org.elasticsearch.client.internal.Client;
11+
import org.elasticsearch.xcontent.XContentParserConfiguration;
12+
13+
import java.util.function.LongSupplier;
14+
15+
/**
16+
* Context object used to rewrite {@link QueryBuilder} instances into simplified version on the datanode where the request is going to be
17+
* executed.
18+
*
19+
* Note: the way search requests are executed and rewritten currently on each node is that it is done by shard. So, `DataRewriteContext`
20+
* will be used in `rewrite` per shard but before the query phase.
21+
*/
22+
public class DataRewriteContext extends QueryRewriteContext {
23+
public DataRewriteContext(final XContentParserConfiguration parserConfiguration, final Client client, final LongSupplier nowInMillis) {
24+
super(parserConfiguration, client, nowInMillis);
25+
}
26+
27+
@Override
28+
public DataRewriteContext convertToDataRewriteContext() {
29+
return this;
30+
}
31+
}

server/src/main/java/org/elasticsearch/index/query/QueryRewriteContext.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,13 @@ public QueryRewriteContext convertToIndexMetadataContext() {
148148
return mapperService != null ? this : null;
149149
}
150150

151+
/**
152+
* Returns an instance of {@link DataRewriteContext} if available or null otherwise
153+
*/
154+
public DataRewriteContext convertToDataRewriteContext() {
155+
return null;
156+
}
157+
151158
/**
152159
* Returns the {@link MappedFieldType} for the provided field name.
153160
* If the field is not mapped, the behaviour depends on the index.query.parse.allow_unmapped_fields setting, which defaults to true.

server/src/main/java/org/elasticsearch/indices/IndicesService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
import org.elasticsearch.index.merge.MergeStats;
101101
import org.elasticsearch.index.query.BoolQueryBuilder;
102102
import org.elasticsearch.index.query.CoordinatorRewriteContextProvider;
103+
import org.elasticsearch.index.query.DataRewriteContext;
103104
import org.elasticsearch.index.query.QueryBuilder;
104105
import org.elasticsearch.index.query.QueryRewriteContext;
105106
import org.elasticsearch.index.recovery.RecoveryStats;
@@ -1699,6 +1700,10 @@ public QueryRewriteContext getRewriteContext(LongSupplier nowInMillis) {
16991700
return new QueryRewriteContext(parserConfig, client, nowInMillis);
17001701
}
17011702

1703+
public DataRewriteContext getDataRewriteContext(LongSupplier nowInMillis) {
1704+
return new DataRewriteContext(parserConfig, client, nowInMillis);
1705+
}
1706+
17021707
public CoordinatorRewriteContextProvider getCoordinatorRewriteContextProvider(LongSupplier nowInMillis) {
17031708
return new CoordinatorRewriteContextProvider(parserConfig, client, nowInMillis, clusterService::state, this::getTimestampFieldType);
17041709
}

server/src/main/java/org/elasticsearch/search/SearchService.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,10 +1662,10 @@ private void rewriteAndFetchShardRequest(IndexShard shard, ShardSearchRequest re
16621662
shard.ensureShardSearchActive(b -> l.onResponse(request));
16631663
}
16641664
});
1665-
// we also do rewrite on the coordinating node (TransportSearchService) but we also need to do it here for BWC as well as
1666-
// AliasFilters that might need to be rewritten. These are edge-cases but we are every efficient doing the rewrite here so it's not
1667-
// adding a lot of overhead
1668-
Rewriteable.rewriteAndFetch(request.getRewriteable(), indicesService.getRewriteContext(request::nowInMillis), actionListener);
1665+
// we also do rewrite on the coordinating node (TransportSearchService) but we also need to do it here.
1666+
// AliasFilters and other things may need to be rewritten on the data node, but not per individual shard.
1667+
// These are uncommon-cases but we are very efficient doing the rewrite here.
1668+
Rewriteable.rewriteAndFetch(request.getRewriteable(), indicesService.getDataRewriteContext(request::nowInMillis), actionListener);
16691669
}
16701670

16711671
/**

test/framework/src/main/java/org/elasticsearch/test/AbstractBuilderTestCase.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import org.elasticsearch.index.mapper.MapperRegistry;
4747
import org.elasticsearch.index.mapper.MapperService;
4848
import org.elasticsearch.index.query.CoordinatorRewriteContext;
49+
import org.elasticsearch.index.query.DataRewriteContext;
4950
import org.elasticsearch.index.query.QueryRewriteContext;
5051
import org.elasticsearch.index.query.SearchExecutionContext;
5152
import org.elasticsearch.index.shard.IndexLongFieldRange;
@@ -332,6 +333,10 @@ protected static CoordinatorRewriteContext createCoordinatorRewriteContext(
332333
return serviceHolder.createCoordinatorContext(dateFieldType, min, max);
333334
}
334335

336+
protected static DataRewriteContext dataRewriteContext() {
337+
return serviceHolder.createDataContext();
338+
}
339+
335340
/**
336341
* @return a new {@link SearchExecutionContext} based on an index with no type registered
337342
*/
@@ -610,6 +615,10 @@ CoordinatorRewriteContext createCoordinatorContext(DateFieldMapper.DateFieldType
610615
);
611616
}
612617

618+
DataRewriteContext createDataContext() {
619+
return new DataRewriteContext(parserConfiguration, this.client, () -> nowInMillis);
620+
}
621+
613622
ScriptModule createScriptModule(List<ScriptPlugin> scriptPlugins) {
614623
if (scriptPlugins == null || scriptPlugins.isEmpty()) {
615624
return new ScriptModule(Settings.EMPTY, singletonList(new ScriptPlugin() {

x-pack/plugin/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ testClusters.configureEach {
224224
extraConfigFile serviceTokens.name, serviceTokens
225225

226226
requiresFeature 'es.index_mode_feature_flag_registered', Version.fromString("8.0.0")
227+
requiresFeature 'es.inference_rescorer_feature_flag_enabled', Version.fromString("8.10.0")
227228
}
228229

229230
tasks.register('enforceApiSpecsConvention').configure {

x-pack/plugin/ml/qa/basic-multi-node/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import org.elasticsearch.gradle.Version
12
import org.elasticsearch.gradle.internal.info.BuildParams
23

34
apply plugin: 'elasticsearch.legacy-java-rest-test'
@@ -12,6 +13,7 @@ testClusters.configureEach {
1213
setting 'xpack.license.self_generated.type', 'trial'
1314
setting 'indices.lifecycle.history_index_enabled', 'false'
1415
setting 'slm.history_index_enabled', 'false'
16+
requiresFeature 'es.inference_rescorer_feature_flag_enabled', Version.fromString("8.10.0")
1517
}
1618

1719
if (BuildParams.inFipsJvm){

0 commit comments

Comments
 (0)