diff --git a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/EvalQueryQuality.java b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/EvalQueryQuality.java index a42ce60c4e4..28162c47441 100644 --- a/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/EvalQueryQuality.java +++ b/modules/rank-eval/src/main/java/org/elasticsearch/index/rankeval/EvalQueryQuality.java @@ -39,7 +39,7 @@ public class EvalQueryQuality implements ToXContent, Writeable { private final String queryId; private final double evaluationResult; private MetricDetails optionalMetricDetails; - private final List hits = new ArrayList<>(); + private final List ratedHits = new ArrayList<>(); public EvalQueryQuality(String id, double evaluationResult) { this.queryId = id; @@ -48,7 +48,7 @@ public class EvalQueryQuality implements ToXContent, Writeable { public EvalQueryQuality(StreamInput in) throws IOException { this(in.readString(), in.readDouble()); - this.hits.addAll(in.readList(RatedSearchHit::new)); + this.ratedHits.addAll(in.readList(RatedSearchHit::new)); this.optionalMetricDetails = in.readOptionalNamedWriteable(MetricDetails.class); } @@ -56,7 +56,7 @@ public class EvalQueryQuality implements ToXContent, Writeable { public void writeTo(StreamOutput out) throws IOException { out.writeString(queryId); out.writeDouble(evaluationResult); - out.writeList(hits); + out.writeList(ratedHits); out.writeOptionalNamedWriteable(this.optionalMetricDetails); } @@ -77,11 +77,11 @@ public class EvalQueryQuality implements ToXContent, Writeable { } public void addHitsAndRatings(List hits) { - this.hits.addAll(hits); + this.ratedHits.addAll(hits); } public List getHitsAndRatings() { - return this.hits; + return this.ratedHits; } @Override @@ -89,7 +89,7 @@ public class EvalQueryQuality implements ToXContent, Writeable { builder.startObject(queryId); builder.field("quality_level", this.evaluationResult); builder.startArray("unknown_docs"); - for (DocumentKey key : EvaluationMetric.filterUnknownDocuments(hits)) { + for (DocumentKey key : EvaluationMetric.filterUnknownDocuments(ratedHits)) { builder.startObject(); builder.field(RatedDocument.INDEX_FIELD.getPreferredName(), key.getIndex()); builder.field(RatedDocument.DOC_ID_FIELD.getPreferredName(), key.getDocId()); @@ -97,7 +97,7 @@ public class EvalQueryQuality implements ToXContent, Writeable { } builder.endArray(); builder.startArray("hits"); - for (RatedSearchHit hit : hits) { + for (RatedSearchHit hit : ratedHits) { hit.toXContent(builder, params); } builder.endArray(); @@ -121,12 +121,12 @@ public class EvalQueryQuality implements ToXContent, Writeable { EvalQueryQuality other = (EvalQueryQuality) obj; return Objects.equals(queryId, other.queryId) && Objects.equals(evaluationResult, other.evaluationResult) && - Objects.equals(hits, other.hits) && + Objects.equals(ratedHits, other.ratedHits) && Objects.equals(optionalMetricDetails, other.optionalMetricDetails); } @Override public final int hashCode() { - return Objects.hash(queryId, evaluationResult, hits, optionalMetricDetails); + return Objects.hash(queryId, evaluationResult, ratedHits, optionalMetricDetails); } } diff --git a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalResponseTests.java b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalResponseTests.java index e1264c02f67..827f7be4442 100644 --- a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalResponseTests.java +++ b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalResponseTests.java @@ -19,20 +19,28 @@ package org.elasticsearch.index.rankeval; +import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.text.Text; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.common.xcontent.XContentLocation; import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.index.rankeval.RatedDocument.DocumentKey; +import org.elasticsearch.index.Index; +import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.SearchShardTarget; import org.elasticsearch.test.ESTestCase; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; public class RankEvalResponseTests extends ESTestCase { @@ -41,13 +49,14 @@ public class RankEvalResponseTests extends ESTestCase { Map partials = new HashMap<>(numberOfRequests); for (int i = 0; i < numberOfRequests; i++) { String id = randomAlphaOfLengthBetween(3, 10); - int numberOfUnknownDocs = randomIntBetween(0, 5); - List unknownDocs = new ArrayList<>(numberOfUnknownDocs); - for (int d = 0; d < numberOfUnknownDocs; d++) { - unknownDocs.add(new DocumentKey(randomAlphaOfLength(10), randomAlphaOfLength(10))); - } EvalQueryQuality evalQuality = new EvalQueryQuality(id, randomDoubleBetween(0.0, 1.0, true)); + int numberOfDocs = randomIntBetween(0, 5); + List ratedHits = new ArrayList<>(numberOfDocs); + for (int d = 0; d < numberOfDocs; d++) { + ratedHits.add(searchHit(randomAlphaOfLength(10), randomIntBetween(0, 1000), randomIntBetween(0, 10))); + } + evalQuality.addHitsAndRatings(ratedHits); partials.put(id, evalQuality); } int numberOfErrors = randomIntBetween(0, 2); @@ -76,12 +85,39 @@ public class RankEvalResponseTests extends ESTestCase { } public void testToXContent() throws IOException { - RankEvalResponse randomResponse = createRandomResponse(); + EvalQueryQuality coffeeQueryQuality = new EvalQueryQuality("coffee_query", 0.1); + coffeeQueryQuality.addHitsAndRatings(Arrays.asList(searchHit("index", 123, 5), searchHit("index", 456, null))); + RankEvalResponse response = new RankEvalResponse(0.123, Collections.singletonMap("coffee_query", coffeeQueryQuality), + Collections.singletonMap("beer_query", new ParsingException(new XContentLocation(0, 0), "someMsg"))); XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON); - if (ESTestCase.randomBoolean()) { - builder.prettyPrint(); - } - randomResponse.toXContent(builder, ToXContent.EMPTY_PARAMS); - // TODO check the correctness of the output + String xContent = response.toXContent(builder, ToXContent.EMPTY_PARAMS).bytes().utf8ToString(); + assertEquals(("{" + + " \"rank_eval\": {" + + " \"quality_level\": 0.123," + + " \"details\": {" + + " \"coffee_query\": {" + + " \"quality_level\": 0.1," + + " \"unknown_docs\": [{\"_index\":\"index\",\"_id\":\"456\"}]," + + " \"hits\":[{\"hit\":{\"_index\":\"index\",\"_type\":\"\",\"_id\":\"123\",\"_score\":1.0}," + + " \"rating\":5}," + + " {\"hit\":{\"_index\":\"index\",\"_type\":\"\",\"_id\":\"456\",\"_score\":1.0}," + + " \"rating\":null}" + + " ]" + + " }" + + " }," + + " \"failures\": {" + + " \"beer_query\": {" + + " \"error\": \"ParsingException[someMsg]\"" + + " }" + + " }" + + " }" + + "}").replaceAll("\\s+", ""), xContent); + } + + private static RatedSearchHit searchHit(String index, int docId, Integer rating) { + SearchHit hit = new SearchHit(docId, docId + "", new Text(""), Collections.emptyMap()); + hit.shard(new SearchShardTarget("testnode", new Index(index, "uuid"), 0, null)); + hit.score(1.0f); + return new RatedSearchHit(hit, rating != null ? Optional.of(rating) : Optional.empty()); } }