diff --git a/server/src/main/java/org/elasticsearch/TransportVersions.java b/server/src/main/java/org/elasticsearch/TransportVersions.java index cde09d33516c9..c75f4539ab237 100644 --- a/server/src/main/java/org/elasticsearch/TransportVersions.java +++ b/server/src/main/java/org/elasticsearch/TransportVersions.java @@ -178,6 +178,7 @@ static TransportVersion def(int id) { public static final TransportVersion REVERT_REMOVE_MIN_COMPATIBLE_SHARD_NODE = def(8_774_00_0); public static final TransportVersion ESQL_FIELD_ATTRIBUTE_PARENT_SIMPLIFIED = def(8_775_00_0); public static final TransportVersion INFERENCE_DONT_PERSIST_ON_READ = def(8_776_00_0); + public static final TransportVersion QUERY_RULES_RETRIEVER = def(8_777_00_0); /* * STOP! READ THIS FIRST! No, really, diff --git a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/rules/80_query_rules_retriever.yml b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/rules/80_query_rules_retriever.yml index 53a02bdcd578a..70f668934ea20 100644 --- a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/rules/80_query_rules_retriever.yml +++ b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/rules/80_query_rules_retriever.yml @@ -281,8 +281,8 @@ setup: explain: true - match: { hits.hits.0._id: foo } - - match: { hits.hits.0._explanation.value: 1 } - - match: { hits.hits.0._explanation.description: "doc [0] with an original score of [1.7014124E38] is at rank [1] from the following source queries." } + - match: { hits.hits.0._explanation.value: 1.7014124430769804E38 } + - match: { hits.hits.0._explanation.description: "query rules evaluated rules from rulesets [test-ruleset] and match criteria {bar=bar, foo=foo}" } - match: { hits.hits.0._explanation.details.0.value: 1 } - match: { hits.hits.0._explanation.details.0.description: "doc [0] with an original score of [1.7014124E38] is at rank [1] from the following source queries." } - match: { hits.hits.0._explanation.details.0.details.0.description: "sum of:" } diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/retriever/QueryRuleRankDoc.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/retriever/QueryRuleRankDoc.java new file mode 100644 index 0000000000000..a62425a92d790 --- /dev/null +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/retriever/QueryRuleRankDoc.java @@ -0,0 +1,102 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.application.rules.retriever; + +import org.apache.lucene.search.Explanation; +import org.elasticsearch.TransportVersion; +import org.elasticsearch.TransportVersions; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.search.rank.RankDoc; +import org.elasticsearch.xcontent.XContentBuilder; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +public class QueryRuleRankDoc extends RankDoc { + + public static final String NAME = "query_rule_rank_doc"; + + public final List rulesetIds; + public final Map matchCriteria; + + public QueryRuleRankDoc(int doc, float score, int shardIndex, List rulesetIds, Map matchCriteria) { + super(doc, score, shardIndex); + this.rulesetIds = rulesetIds; + this.matchCriteria = matchCriteria; + } + + public QueryRuleRankDoc(StreamInput in) throws IOException { + super(in); + rulesetIds = in.readStringCollectionAsImmutableList(); + matchCriteria = in.readGenericMap(); + } + + @Override + public Explanation explain(Explanation[] sources, String[] queryNames) { + + return Explanation.match( + score, + "query rules evaluated rules from rulesets " + rulesetIds + " and match criteria " + matchCriteria, + sources + ); + } + + @Override + public void doWriteTo(StreamOutput out) throws IOException { + out.writeStringCollection(rulesetIds); + out.writeGenericMap(matchCriteria); + } + + @Override + public boolean doEquals(RankDoc rd) { + QueryRuleRankDoc qrrd = (QueryRuleRankDoc) rd; + return Objects.equals(rulesetIds, qrrd.rulesetIds) && Objects.equals(matchCriteria, qrrd.matchCriteria); + } + + @Override + public int doHashCode() { + return Objects.hash(rulesetIds, matchCriteria); + } + + @Override + public String toString() { + return "QueryRuleRankDoc{" + + "doc=" + + doc + + ", shardIndex=" + + shardIndex + + ", score=" + + score + + ", rulesetIds=" + + rulesetIds + + ", matchCriteria=" + + matchCriteria + + "}"; + } + + @Override + public String getWriteableName() { + return NAME; + } + + @Override + protected void doToXContent(XContentBuilder builder, Params params) throws IOException { + builder.array("rulesetIds", rulesetIds.toArray()); + builder.startObject("matchCriteria"); + builder.mapContents(matchCriteria); + builder.endObject(); + } + + @Override + public TransportVersion getMinimalSupportedVersion() { + return TransportVersions.QUERY_RULES_RETRIEVER; + } +} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/retriever/QueryRuleRetrieverBuilder.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/retriever/QueryRuleRetrieverBuilder.java index c146a18acd7fc..6964b248287d4 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/retriever/QueryRuleRetrieverBuilder.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/retriever/QueryRuleRetrieverBuilder.java @@ -160,10 +160,10 @@ protected QueryRuleRetrieverBuilder clone(List newChildRetrieve protected RankDoc[] combineInnerRetrieverResults(List rankResults) { assert rankResults.size() == 1; ScoreDoc[] scoreDocs = rankResults.getFirst(); - RankDoc[] rankDocs = new RankDoc[scoreDocs.length]; + RankDoc[] rankDocs = new QueryRuleRankDoc[scoreDocs.length]; for (int i = 0; i < scoreDocs.length; i++) { ScoreDoc scoreDoc = scoreDocs[i]; - rankDocs[i] = new RankDoc(scoreDoc.doc, scoreDoc.score, scoreDoc.shardIndex); + rankDocs[i] = new QueryRuleRankDoc(scoreDoc.doc, scoreDoc.score, scoreDoc.shardIndex, rulesetIds, matchCriteria); rankDocs[i].rank = i + 1; } return rankDocs;