From a7f26f3a4cffa3832be0e4d45040a826d7da89d6 Mon Sep 17 00:00:00 2001 From: Mridula Date: Thu, 2 Oct 2025 14:30:57 +0100 Subject: [PATCH 1/9] Removed the TODO --- .../xpack/core/ml/search/SparseVectorQueryBuilder.java | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java index a36f87e939673..2ee61b97db447 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java @@ -272,7 +272,6 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) { throw new IllegalArgumentException("inference_id required to perform vector search on query string"); } - // TODO move this to xpack core and use inference APIs CoordinatedInferenceAction.Request inferRequest = CoordinatedInferenceAction.Request.forTextInput( inferenceId, List.of(query), From 2b3a9911e2d11ea132e1022960adf8dce55ecde8 Mon Sep 17 00:00:00 2001 From: Mridula Date: Thu, 2 Oct 2025 16:26:26 +0100 Subject: [PATCH 2/9] Updated the sparevector similar to Semantic query builder --- .../ml/search/SparseVectorQueryBuilder.java | 90 +++++++++++-------- 1 file changed, 53 insertions(+), 37 deletions(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java index 2ee61b97db447..4d85bf07ba6e6 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java @@ -25,16 +25,16 @@ import org.elasticsearch.index.query.QueryRewriteContext; import org.elasticsearch.index.query.SearchExecutionContext; import org.elasticsearch.inference.InferenceResults; +import org.elasticsearch.inference.InputType; +import org.elasticsearch.inference.TaskType; import org.elasticsearch.inference.WeightedToken; import org.elasticsearch.xcontent.ConstructingObjectParser; import org.elasticsearch.xcontent.ParseField; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentParser; -import org.elasticsearch.xpack.core.ml.action.CoordinatedInferenceAction; -import org.elasticsearch.xpack.core.ml.inference.TrainedModelPrefixStrings; +import org.elasticsearch.xpack.core.inference.action.InferenceAction; import org.elasticsearch.xpack.core.ml.inference.results.TextExpansionResults; import org.elasticsearch.xpack.core.ml.inference.results.WarningInferenceResults; -import org.elasticsearch.xpack.core.ml.inference.trainedmodel.TextExpansionConfigUpdate; import java.io.IOException; import java.util.ArrayList; @@ -272,53 +272,38 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) { throw new IllegalArgumentException("inference_id required to perform vector search on query string"); } - CoordinatedInferenceAction.Request inferRequest = CoordinatedInferenceAction.Request.forTextInput( + InferenceAction.Request inferenceRequest = new InferenceAction.Request( + TaskType.ANY, inferenceId, + null, + null, + null, List.of(query), - TextExpansionConfigUpdate.EMPTY_UPDATE, - false, - null + Map.of(), + InputType.INTERNAL_SEARCH, + null, + false ); - inferRequest.setHighPriority(true); - inferRequest.setPrefixType(TrainedModelPrefixStrings.PrefixType.SEARCH); SetOnce textExpansionResultsSupplier = new SetOnce<>(); queryRewriteContext.registerAsyncAction( (client, listener) -> executeAsyncWithOrigin( client, ML_ORIGIN, - CoordinatedInferenceAction.INSTANCE, - inferRequest, + InferenceAction.INSTANCE, + inferenceRequest, ActionListener.wrap(inferenceResponse -> { - - List inferenceResults = inferenceResponse.getInferenceResults(); - if (inferenceResults.isEmpty()) { - listener.onFailure(new IllegalStateException("inference response contain no results")); - return; - } - if (inferenceResults.size() > 1) { - listener.onFailure(new IllegalStateException("inference response should contain only one result")); + List inferenceResults = inferenceResponse.getResults().transformToCoordinationFormat(); + TextExpansionResults textExpansionResults; + try { + textExpansionResults = validateAndExtractTextExpansionResults(inferenceResults, inferenceId); + } catch (Exception e) { + listener.onFailure(e); return; } - if (inferenceResults.get(0) instanceof TextExpansionResults textExpansionResults) { - textExpansionResultsSupplier.set(textExpansionResults); - listener.onResponse(null); - } else if (inferenceResults.get(0) instanceof WarningInferenceResults warning) { - listener.onFailure(new IllegalStateException(warning.getWarning())); - } else { - listener.onFailure( - new IllegalArgumentException( - "expected a result of type [" - + TextExpansionResults.NAME - + "] received [" - + inferenceResults.get(0).getWriteableName() - + "]. Is [" - + inferenceId - + "] a compatible model?" - ) - ); - } + textExpansionResultsSupplier.set(textExpansionResults); + listener.onResponse(null); }, listener::onFailure) ) ); @@ -326,6 +311,37 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) { return new SparseVectorQueryBuilder(this, textExpansionResultsSupplier); } + private static TextExpansionResults validateAndExtractTextExpansionResults( + List inferenceResults, + String inferenceId + ) { + if (inferenceResults.isEmpty()) { + throw new IllegalStateException("inference response contain no results"); + } + if (inferenceResults.size() > 1) { + throw new IllegalStateException("inference response should contain only one result"); + } + + InferenceResults result = inferenceResults.getFirst(); + if (result instanceof TextExpansionResults textExpansionResults) { + return textExpansionResults; + } + + if (result instanceof WarningInferenceResults warning) { + throw new IllegalStateException(warning.getWarning()); + } + + throw new IllegalArgumentException( + "expected a result of type [" + + TextExpansionResults.NAME + + "] received [" + + result.getWriteableName() + + "]. Is [" + + inferenceId + + "] a compatible model?" + ); + } + @Override protected boolean doEquals(SparseVectorQueryBuilder other) { return Objects.equals(fieldName, other.fieldName) From 5429d08f3dbb2c530429b2bf0c57d7c11a6a05f4 Mon Sep 17 00:00:00 2001 From: Mridula Date: Wed, 22 Oct 2025 13:37:54 +0100 Subject: [PATCH 3/9] Update docs/changelog/134702.yaml --- docs/changelog/134702.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/changelog/134702.yaml diff --git a/docs/changelog/134702.yaml b/docs/changelog/134702.yaml new file mode 100644 index 0000000000000..4f5a4ec6de62f --- /dev/null +++ b/docs/changelog/134702.yaml @@ -0,0 +1,5 @@ +pr: 134702 +summary: "Cleanup: Align `SparseVectorQueryBuilder` with `InferenceAction`" +area: Relevance +type: tech debt +issues: [] From 1da4a6694411596893fc6dfe9391688a83dbc210 Mon Sep 17 00:00:00 2001 From: Mridula Date: Wed, 29 Oct 2025 11:42:47 +0000 Subject: [PATCH 4/9] Remove obsolete TODO comment from SparseVectorQueryBuilder --- .../ml/search/SparseVectorQueryBuilder.java | 91 ++++++++----------- 1 file changed, 38 insertions(+), 53 deletions(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java index c65692cc593b1..0eda041a591f6 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java @@ -25,16 +25,16 @@ import org.elasticsearch.index.query.QueryRewriteContext; import org.elasticsearch.index.query.SearchExecutionContext; import org.elasticsearch.inference.InferenceResults; -import org.elasticsearch.inference.InputType; -import org.elasticsearch.inference.TaskType; import org.elasticsearch.inference.WeightedToken; import org.elasticsearch.xcontent.ConstructingObjectParser; import org.elasticsearch.xcontent.ParseField; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentParser; -import org.elasticsearch.xpack.core.inference.action.InferenceAction; +import org.elasticsearch.xpack.core.ml.action.CoordinatedInferenceAction; +import org.elasticsearch.xpack.core.ml.inference.TrainedModelPrefixStrings; import org.elasticsearch.xpack.core.ml.inference.results.TextExpansionResults; import org.elasticsearch.xpack.core.ml.inference.results.WarningInferenceResults; +import org.elasticsearch.xpack.core.ml.inference.trainedmodel.TextExpansionConfigUpdate; import java.io.IOException; import java.util.ArrayList; @@ -271,38 +271,54 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) { throw new IllegalArgumentException("inference_id required to perform vector search on query string"); } - InferenceAction.Request inferenceRequest = new InferenceAction.Request( - TaskType.ANY, + + CoordinatedInferenceAction.Request inferRequest = CoordinatedInferenceAction.Request.forTextInput( inferenceId, - null, - null, - null, List.of(query), - Map.of(), - InputType.INTERNAL_SEARCH, - null, - false + TextExpansionConfigUpdate.EMPTY_UPDATE, + false, + null ); + inferRequest.setHighPriority(true); + inferRequest.setPrefixType(TrainedModelPrefixStrings.PrefixType.SEARCH); SetOnce textExpansionResultsSupplier = new SetOnce<>(); queryRewriteContext.registerAsyncAction( (client, listener) -> executeAsyncWithOrigin( client, ML_ORIGIN, - InferenceAction.INSTANCE, - inferenceRequest, + CoordinatedInferenceAction.INSTANCE, + inferRequest, ActionListener.wrap(inferenceResponse -> { - List inferenceResults = inferenceResponse.getResults().transformToCoordinationFormat(); - TextExpansionResults textExpansionResults; - try { - textExpansionResults = validateAndExtractTextExpansionResults(inferenceResults, inferenceId); - } catch (Exception e) { - listener.onFailure(e); + + List inferenceResults = inferenceResponse.getInferenceResults(); + if (inferenceResults.isEmpty()) { + listener.onFailure(new IllegalStateException("inference response contain no results")); + return; + } + if (inferenceResults.size() > 1) { + listener.onFailure(new IllegalStateException("inference response should contain only one result")); return; } - textExpansionResultsSupplier.set(textExpansionResults); - listener.onResponse(null); + if (inferenceResults.get(0) instanceof TextExpansionResults textExpansionResults) { + textExpansionResultsSupplier.set(textExpansionResults); + listener.onResponse(null); + } else if (inferenceResults.get(0) instanceof WarningInferenceResults warning) { + listener.onFailure(new IllegalStateException(warning.getWarning())); + } else { + listener.onFailure( + new IllegalArgumentException( + "expected a result of type [" + + TextExpansionResults.NAME + + "] received [" + + inferenceResults.get(0).getWriteableName() + + "]. Is [" + + inferenceId + + "] a compatible model?" + ) + ); + } }, listener::onFailure) ) ); @@ -310,37 +326,6 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) { return new SparseVectorQueryBuilder(this, textExpansionResultsSupplier); } - private static TextExpansionResults validateAndExtractTextExpansionResults( - List inferenceResults, - String inferenceId - ) { - if (inferenceResults.isEmpty()) { - throw new IllegalStateException("inference response contain no results"); - } - if (inferenceResults.size() > 1) { - throw new IllegalStateException("inference response should contain only one result"); - } - - InferenceResults result = inferenceResults.getFirst(); - if (result instanceof TextExpansionResults textExpansionResults) { - return textExpansionResults; - } - - if (result instanceof WarningInferenceResults warning) { - throw new IllegalStateException(warning.getWarning()); - } - - throw new IllegalArgumentException( - "expected a result of type [" - + TextExpansionResults.NAME - + "] received [" - + result.getWriteableName() - + "]. Is [" - + inferenceId - + "] a compatible model?" - ); - } - @Override protected boolean doEquals(SparseVectorQueryBuilder other) { return Objects.equals(fieldName, other.fieldName) From 9c1eb88f0e2698559e7f2e3b06dda118ed034607 Mon Sep 17 00:00:00 2001 From: elasticsearchmachine Date: Wed, 29 Oct 2025 11:53:45 +0000 Subject: [PATCH 5/9] [CI] Auto commit changes from spotless --- .../xpack/core/ml/search/SparseVectorQueryBuilder.java | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java index 0eda041a591f6..a59bf63830bfd 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java @@ -271,7 +271,6 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) { throw new IllegalArgumentException("inference_id required to perform vector search on query string"); } - CoordinatedInferenceAction.Request inferRequest = CoordinatedInferenceAction.Request.forTextInput( inferenceId, List.of(query), From 8973b947cd41651296d5d7fe0df172f1eded8056 Mon Sep 17 00:00:00 2001 From: Mridula Date: Wed, 29 Oct 2025 13:22:27 +0000 Subject: [PATCH 6/9] Modified the TODO to make more sense --- .../xpack/core/ml/search/SparseVectorQueryBuilder.java | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java index a59bf63830bfd..eaf6392c76388 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java @@ -271,6 +271,7 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) { throw new IllegalArgumentException("inference_id required to perform vector search on query string"); } + // TODO(server): once search-time inference APIs exist in the server module, switch this to InferenceAction.Request CoordinatedInferenceAction.Request inferRequest = CoordinatedInferenceAction.Request.forTextInput( inferenceId, List.of(query), From aad211dee08a38737b9ffa69d581d11c9c4c75fd Mon Sep 17 00:00:00 2001 From: Mridula Date: Wed, 29 Oct 2025 13:45:30 +0000 Subject: [PATCH 7/9] Delete docs/changelog/134702.yaml --- docs/changelog/134702.yaml | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 docs/changelog/134702.yaml diff --git a/docs/changelog/134702.yaml b/docs/changelog/134702.yaml deleted file mode 100644 index 4f5a4ec6de62f..0000000000000 --- a/docs/changelog/134702.yaml +++ /dev/null @@ -1,5 +0,0 @@ -pr: 134702 -summary: "Cleanup: Align `SparseVectorQueryBuilder` with `InferenceAction`" -area: Relevance -type: tech debt -issues: [] From b7569b05a536bb6b68051293bdadb2450dc56e0c Mon Sep 17 00:00:00 2001 From: Mridula Date: Wed, 29 Oct 2025 14:52:17 +0000 Subject: [PATCH 8/9] Update x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java Co-authored-by: Kathleen DeRusso --- .../xpack/core/ml/search/SparseVectorQueryBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java index eaf6392c76388..8222e42e31a3d 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java @@ -271,7 +271,7 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) { throw new IllegalArgumentException("inference_id required to perform vector search on query string"); } - // TODO(server): once search-time inference APIs exist in the server module, switch this to InferenceAction.Request + // Move this class to `server` and update to use InferenceAction.Request CoordinatedInferenceAction.Request inferRequest = CoordinatedInferenceAction.Request.forTextInput( inferenceId, List.of(query), From 0ac0d9449fdceda831a57eec8367da539ace8339 Mon Sep 17 00:00:00 2001 From: Mridula Date: Wed, 29 Oct 2025 19:55:19 +0000 Subject: [PATCH 9/9] Update SparseVectorQueryBuilder.java --- .../xpack/core/ml/search/SparseVectorQueryBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java index 8222e42e31a3d..53fd34d3ffdef 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java @@ -271,7 +271,7 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) { throw new IllegalArgumentException("inference_id required to perform vector search on query string"); } - // Move this class to `server` and update to use InferenceAction.Request + // TODO: Move this class to `server` and update to use InferenceAction.Request CoordinatedInferenceAction.Request inferRequest = CoordinatedInferenceAction.Request.forTextInput( inferenceId, List.of(query),