Add roundtrip xcontent test to DiscountedCumulativeGainAt
This factors the roundtripping out of RatedDocumentTests. Makes RankedListQualityMetric and RatedDocument implement FromXContenBuilder to be able to do the aforementioned refactoring in a generic way. Adds a roundtrip test to DiscountedCumulativeGainAt. Open questions: DiscountedCumulativeGain didn't have a constructor that accepted all possible parameters as arguments. Added one. I guess we still want to keep the one that only requires the position argument? To make roundtripping work I had to change the NAME parameter when generating XContent for DiscountedCumulativeGainAt - all remaining unit tests seem to be passing (haven't checked the REST tests yet) - need to figure out why that was there to begin with.
This commit is contained in:
parent
e5fd0cb3a2
commit
a2a92b9629
|
@ -20,6 +20,7 @@
|
||||||
package org.elasticsearch.index.rankeval;
|
package org.elasticsearch.index.rankeval;
|
||||||
|
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
|
import org.elasticsearch.common.ParseFieldMatcher;
|
||||||
import org.elasticsearch.common.ParseFieldMatcherSupplier;
|
import org.elasticsearch.common.ParseFieldMatcherSupplier;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
|
@ -35,8 +36,9 @@ import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class DiscountedCumulativeGainAt extends RankedListQualityMetric {
|
public class DiscountedCumulativeGainAt extends RankedListQualityMetric<DiscountedCumulativeGainAt> {
|
||||||
|
|
||||||
/** rank position up to which to check results. */
|
/** rank position up to which to check results. */
|
||||||
private int position;
|
private int position;
|
||||||
|
@ -83,6 +85,17 @@ public class DiscountedCumulativeGainAt extends RankedListQualityMetric {
|
||||||
this.position = position;
|
this.position = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param position number of top results to check against a given set of relevant results. Must be positive. // TODO is there a way to enforce this?
|
||||||
|
* @param normalize If set to true, dcg will be normalized (ndcg) See https://en.wikipedia.org/wiki/Discounted_cumulative_gain
|
||||||
|
* @param unknownDocRating the rating for docs the user hasn't supplied an explicit rating for
|
||||||
|
* */
|
||||||
|
public DiscountedCumulativeGainAt(int position, boolean normalize, Integer unknownDocRating) {
|
||||||
|
this.position = position;
|
||||||
|
this.normalize = normalize;
|
||||||
|
this.unknownDocRating = unknownDocRating;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return number of search results to check for quality metric.
|
* Return number of search results to check for quality metric.
|
||||||
*/
|
*/
|
||||||
|
@ -178,13 +191,24 @@ public class DiscountedCumulativeGainAt extends RankedListQualityMetric {
|
||||||
PARSER.declareInt(DiscountedCumulativeGainAt::setUnknownDocRating, UNKNOWN_DOC_RATING_FIELD);
|
PARSER.declareInt(DiscountedCumulativeGainAt::setUnknownDocRating, UNKNOWN_DOC_RATING_FIELD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DiscountedCumulativeGainAt fromXContent(XContentParser parser, ParseFieldMatcher matcher) {
|
||||||
|
return DiscountedCumulativeGainAt.fromXContent(parser, new ParseFieldMatcherSupplier() {
|
||||||
|
@Override
|
||||||
|
public ParseFieldMatcher getParseFieldMatcher() {
|
||||||
|
return matcher;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static DiscountedCumulativeGainAt fromXContent(XContentParser parser, ParseFieldMatcherSupplier matcher) {
|
public static DiscountedCumulativeGainAt fromXContent(XContentParser parser, ParseFieldMatcherSupplier matcher) {
|
||||||
return PARSER.apply(parser, matcher);
|
return PARSER.apply(parser, matcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject(NAME);
|
//builder.startObject(NAME); // TODO roundtrip xcontent only works w/o this, wtf?
|
||||||
|
builder.startObject();
|
||||||
builder.field(SIZE_FIELD.getPreferredName(), this.position);
|
builder.field(SIZE_FIELD.getPreferredName(), this.position);
|
||||||
builder.field(NORMALIZE_FIELD.getPreferredName(), this.normalize);
|
builder.field(NORMALIZE_FIELD.getPreferredName(), this.normalize);
|
||||||
if (unknownDocRating != null) {
|
if (unknownDocRating != null) {
|
||||||
|
@ -193,4 +217,23 @@ public class DiscountedCumulativeGainAt extends RankedListQualityMetric {
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DiscountedCumulativeGainAt other = (DiscountedCumulativeGainAt) obj;
|
||||||
|
return Objects.equals(position, other.position) &&
|
||||||
|
Objects.equals(normalize, other.normalize) &&
|
||||||
|
Objects.equals(unknownDocRating, other.unknownDocRating);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final int hashCode() {
|
||||||
|
return Objects.hash(getClass(), position, normalize, unknownDocRating);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.elasticsearch.index.rankeval;
|
package org.elasticsearch.index.rankeval;
|
||||||
|
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
|
import org.elasticsearch.common.ParseFieldMatcher;
|
||||||
import org.elasticsearch.common.ParseFieldMatcherSupplier;
|
import org.elasticsearch.common.ParseFieldMatcherSupplier;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
|
@ -40,7 +41,7 @@ import javax.naming.directory.SearchResult;
|
||||||
*
|
*
|
||||||
* Documents of unkonwn quality are ignored in the precision at n computation and returned by document id.
|
* Documents of unkonwn quality are ignored in the precision at n computation and returned by document id.
|
||||||
* */
|
* */
|
||||||
public class PrecisionAtN extends RankedListQualityMetric {
|
public class PrecisionAtN extends RankedListQualityMetric<PrecisionAtN> {
|
||||||
|
|
||||||
/** Number of results to check against a given set of relevant results. */
|
/** Number of results to check against a given set of relevant results. */
|
||||||
private int n;
|
private int n;
|
||||||
|
@ -90,6 +91,17 @@ public class PrecisionAtN extends RankedListQualityMetric {
|
||||||
PARSER.declareInt(ConstructingObjectParser.constructorArg(), SIZE_FIELD);
|
PARSER.declareInt(ConstructingObjectParser.constructorArg(), SIZE_FIELD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PrecisionAtN fromXContent(XContentParser parser, ParseFieldMatcher matcher) {
|
||||||
|
return PrecisionAtN.fromXContent(parser, new ParseFieldMatcherSupplier() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ParseFieldMatcher getParseFieldMatcher() {
|
||||||
|
return matcher;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static PrecisionAtN fromXContent(XContentParser parser, ParseFieldMatcherSupplier matcher) {
|
public static PrecisionAtN fromXContent(XContentParser parser, ParseFieldMatcherSupplier matcher) {
|
||||||
return PARSER.apply(parser, matcher);
|
return PARSER.apply(parser, matcher);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.elasticsearch.action.support.ToXContentToBytes;
|
||||||
import org.elasticsearch.common.ParseFieldMatcherSupplier;
|
import org.elasticsearch.common.ParseFieldMatcherSupplier;
|
||||||
import org.elasticsearch.common.ParsingException;
|
import org.elasticsearch.common.ParsingException;
|
||||||
import org.elasticsearch.common.io.stream.NamedWriteable;
|
import org.elasticsearch.common.io.stream.NamedWriteable;
|
||||||
|
import org.elasticsearch.common.xcontent.FromXContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser.Token;
|
import org.elasticsearch.common.xcontent.XContentParser.Token;
|
||||||
|
@ -38,7 +39,9 @@ import java.util.List;
|
||||||
*
|
*
|
||||||
* RelevancyLevel specifies the type of object determining the relevancy level of some known docid.
|
* RelevancyLevel specifies the type of object determining the relevancy level of some known docid.
|
||||||
* */
|
* */
|
||||||
public abstract class RankedListQualityMetric extends ToXContentToBytes implements NamedWriteable {
|
public abstract class RankedListQualityMetric<T extends RankedListQualityMetric>
|
||||||
|
extends ToXContentToBytes
|
||||||
|
implements NamedWriteable, FromXContentBuilder<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a single metric representing the ranking quality of a set of returned documents
|
* Returns a single metric representing the ranking quality of a set of returned documents
|
||||||
|
|
|
@ -21,11 +21,14 @@ package org.elasticsearch.index.rankeval;
|
||||||
|
|
||||||
import org.elasticsearch.action.support.ToXContentToBytes;
|
import org.elasticsearch.action.support.ToXContentToBytes;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
|
import org.elasticsearch.common.ParseFieldMatcher;
|
||||||
|
import org.elasticsearch.common.ParseFieldMatcherSupplier;
|
||||||
import org.elasticsearch.common.ParsingException;
|
import org.elasticsearch.common.ParsingException;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.io.stream.Writeable;
|
import org.elasticsearch.common.io.stream.Writeable;
|
||||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||||
|
import org.elasticsearch.common.xcontent.FromXContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
|
||||||
|
@ -35,12 +38,12 @@ import java.util.Objects;
|
||||||
/**
|
/**
|
||||||
* A document ID and its rating for the query QA use case.
|
* A document ID and its rating for the query QA use case.
|
||||||
* */
|
* */
|
||||||
public class RatedDocument extends ToXContentToBytes implements Writeable {
|
public class RatedDocument extends ToXContentToBytes implements Writeable, FromXContentBuilder<RatedDocument> {
|
||||||
|
|
||||||
public static final ParseField RATING_FIELD = new ParseField("rating");
|
public static final ParseField RATING_FIELD = new ParseField("rating");
|
||||||
public static final ParseField KEY_FIELD = new ParseField("key");
|
public static final ParseField KEY_FIELD = new ParseField("key");
|
||||||
|
|
||||||
private static final ConstructingObjectParser<RatedDocument, RankEvalContext> PARSER = new ConstructingObjectParser<>("rated_document",
|
private static final ConstructingObjectParser<RatedDocument, ParseFieldMatcherSupplier> PARSER = new ConstructingObjectParser<>("rated_document",
|
||||||
a -> new RatedDocument((RatedDocumentKey) a[0], (Integer) a[1]));
|
a -> new RatedDocument((RatedDocumentKey) a[0], (Integer) a[1]));
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
@ -93,8 +96,19 @@ public class RatedDocument extends ToXContentToBytes implements Writeable {
|
||||||
out.writeVInt(rating);
|
out.writeVInt(rating);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RatedDocument fromXContent(XContentParser parser, RankEvalContext context) throws IOException {
|
@Override
|
||||||
return PARSER.apply(parser, context);
|
public RatedDocument fromXContent(XContentParser parser, ParseFieldMatcher parseFieldMatcher) throws IOException {
|
||||||
|
return RatedDocument.fromXContent(parser, new ParseFieldMatcherSupplier() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ParseFieldMatcher getParseFieldMatcher() {
|
||||||
|
return parseFieldMatcher;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RatedDocument fromXContent(XContentParser parser, ParseFieldMatcherSupplier supplier) throws IOException {
|
||||||
|
return PARSER.apply(parser, supplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.elasticsearch.index.rankeval;
|
||||||
|
|
||||||
import org.elasticsearch.action.support.ToXContentToBytes;
|
import org.elasticsearch.action.support.ToXContentToBytes;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
|
import org.elasticsearch.common.ParseFieldMatcherSupplier;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.io.stream.Writeable;
|
import org.elasticsearch.common.io.stream.Writeable;
|
||||||
|
@ -36,7 +37,7 @@ public class RatedDocumentKey extends ToXContentToBytes implements Writeable {
|
||||||
public static final ParseField TYPE_FIELD = new ParseField("type");
|
public static final ParseField TYPE_FIELD = new ParseField("type");
|
||||||
public static final ParseField INDEX_FIELD = new ParseField("index");
|
public static final ParseField INDEX_FIELD = new ParseField("index");
|
||||||
|
|
||||||
private static final ConstructingObjectParser<RatedDocumentKey, RankEvalContext> PARSER = new ConstructingObjectParser<>("ratings",
|
private static final ConstructingObjectParser<RatedDocumentKey, ParseFieldMatcherSupplier> PARSER = new ConstructingObjectParser<>("ratings",
|
||||||
a -> new RatedDocumentKey((String) a[0], (String) a[1], (String) a[2]));
|
a -> new RatedDocumentKey((String) a[0], (String) a[1], (String) a[2]));
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
@ -103,7 +104,7 @@ public class RatedDocumentKey extends ToXContentToBytes implements Writeable {
|
||||||
out.writeString(docId);
|
out.writeString(docId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RatedDocumentKey fromXContent(XContentParser parser, RankEvalContext context) throws IOException {
|
public static RatedDocumentKey fromXContent(XContentParser parser, ParseFieldMatcherSupplier context) throws IOException {
|
||||||
return PARSER.apply(parser, context);
|
return PARSER.apply(parser, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.elasticsearch.index.rankeval;
|
package org.elasticsearch.index.rankeval;
|
||||||
|
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
|
import org.elasticsearch.common.ParseFieldMatcher;
|
||||||
import org.elasticsearch.common.ParseFieldMatcherSupplier;
|
import org.elasticsearch.common.ParseFieldMatcherSupplier;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
|
@ -42,7 +43,7 @@ import javax.naming.directory.SearchResult;
|
||||||
/**
|
/**
|
||||||
* Evaluate reciprocal rank.
|
* Evaluate reciprocal rank.
|
||||||
* */
|
* */
|
||||||
public class ReciprocalRank extends RankedListQualityMetric {
|
public class ReciprocalRank extends RankedListQualityMetric<ReciprocalRank> {
|
||||||
|
|
||||||
public static final String NAME = "reciprocal_rank";
|
public static final String NAME = "reciprocal_rank";
|
||||||
public static final int DEFAULT_MAX_ACCEPTABLE_RANK = 10;
|
public static final int DEFAULT_MAX_ACCEPTABLE_RANK = 10;
|
||||||
|
@ -140,6 +141,17 @@ public class ReciprocalRank extends RankedListQualityMetric {
|
||||||
PARSER.declareInt(ReciprocalRank::setMaxAcceptableRank, MAX_RANK_FIELD);
|
PARSER.declareInt(ReciprocalRank::setMaxAcceptableRank, MAX_RANK_FIELD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ReciprocalRank fromXContent(XContentParser parser, ParseFieldMatcher matcher) {
|
||||||
|
return ReciprocalRank.fromXContent(parser, new ParseFieldMatcherSupplier() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ParseFieldMatcher getParseFieldMatcher() {
|
||||||
|
return matcher;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static ReciprocalRank fromXContent(XContentParser parser, ParseFieldMatcherSupplier matcher) {
|
public static ReciprocalRank fromXContent(XContentParser parser, ParseFieldMatcherSupplier matcher) {
|
||||||
return PARSER.apply(parser, matcher);
|
return PARSER.apply(parser, matcher);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.shard.ShardId;
|
import org.elasticsearch.index.shard.ShardId;
|
||||||
import org.elasticsearch.search.SearchShardTarget;
|
import org.elasticsearch.search.SearchShardTarget;
|
||||||
import org.elasticsearch.search.internal.InternalSearchHit;
|
import org.elasticsearch.search.internal.InternalSearchHit;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -34,7 +33,7 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
public class DiscountedCumulativeGainAtTests extends ESTestCase {
|
public class DiscountedCumulativeGainAtTests extends XContentRoundtripTestCase<DiscountedCumulativeGainAt> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assuming the docs are ranked in the following order:
|
* Assuming the docs are ranked in the following order:
|
||||||
|
@ -121,4 +120,13 @@ public class DiscountedCumulativeGainAtTests extends ESTestCase {
|
||||||
assertEquals(8, dcgAt.getPosition());
|
assertEquals(8, dcgAt.getPosition());
|
||||||
assertEquals(true, dcgAt.getNormalize());
|
assertEquals(true, dcgAt.getNormalize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testXContentRoundtrip() throws IOException {
|
||||||
|
int position = randomIntBetween(0, 1000);
|
||||||
|
boolean normalize = randomBoolean();
|
||||||
|
Integer unknownDocRating = new Integer(randomIntBetween(0, 1000));
|
||||||
|
|
||||||
|
DiscountedCumulativeGainAt testItem = new DiscountedCumulativeGainAt(position, normalize, unknownDocRating);
|
||||||
|
roundtrip(testItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,41 +19,17 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.rankeval;
|
package org.elasticsearch.index.rankeval;
|
||||||
|
|
||||||
import org.elasticsearch.common.ParseFieldMatcher;
|
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentType;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class RatedDocumentTests extends ESTestCase {
|
public class RatedDocumentTests extends XContentRoundtripTestCase<RatedDocument> {
|
||||||
|
|
||||||
public void testXContentParsing() throws IOException {
|
public void testXContentParsing() throws IOException {
|
||||||
String index = randomAsciiOfLength(10);
|
String index = randomAsciiOfLength(10);
|
||||||
String type = randomAsciiOfLength(10);
|
String type = randomAsciiOfLength(10);
|
||||||
String docId = randomAsciiOfLength(10);
|
String docId = randomAsciiOfLength(10);
|
||||||
int rating = randomInt();
|
int rating = randomInt();
|
||||||
|
|
||||||
RatedDocument testItem = new RatedDocument(new RatedDocumentKey(index, type, docId), rating);
|
RatedDocument testItem = new RatedDocument(new RatedDocumentKey(index, type, docId), rating);
|
||||||
|
roundtrip(testItem);
|
||||||
XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values()));
|
|
||||||
if (randomBoolean()) {
|
|
||||||
builder.prettyPrint();
|
|
||||||
}
|
|
||||||
testItem.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
|
||||||
XContentBuilder shuffled = shuffleXContent(builder);
|
|
||||||
XContentParser itemParser = XContentHelper.createParser(shuffled.bytes());
|
|
||||||
itemParser.nextToken();
|
|
||||||
|
|
||||||
RankEvalContext context = new RankEvalContext(ParseFieldMatcher.STRICT, null, null);
|
|
||||||
RatedDocument parsedItem = RatedDocument.fromXContent(itemParser, context);
|
|
||||||
assertNotSame(testItem, parsedItem);
|
|
||||||
assertEquals(testItem, parsedItem);
|
|
||||||
assertEquals(testItem.hashCode(), parsedItem.hashCode());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.index.rankeval;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.support.ToXContentToBytes;
|
||||||
|
import org.elasticsearch.common.ParseFieldMatcher;
|
||||||
|
import org.elasticsearch.common.xcontent.FromXContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentType;
|
||||||
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class XContentRoundtripTestCase<T extends ToXContentToBytes & FromXContentBuilder<T>> extends ESTestCase {
|
||||||
|
|
||||||
|
public void roundtrip(T testItem) throws IOException {
|
||||||
|
XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values()));
|
||||||
|
if (randomBoolean()) {
|
||||||
|
builder.prettyPrint();
|
||||||
|
}
|
||||||
|
testItem.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
||||||
|
XContentBuilder shuffled = shuffleXContent(builder);
|
||||||
|
XContentParser itemParser = XContentHelper.createParser(shuffled.bytes());
|
||||||
|
itemParser.nextToken();
|
||||||
|
T parsedItem = testItem.fromXContent(itemParser, ParseFieldMatcher.STRICT);
|
||||||
|
assertNotSame(testItem, parsedItem);
|
||||||
|
assertEquals(testItem, parsedItem);
|
||||||
|
assertEquals(testItem.hashCode(), parsedItem.hashCode());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue