Remove nested `key` field for rated documents
Every rated document needs an index/type/id parameter, so adding a "key" object like we currently do only leads to an additional unneeded level of nesting in the rest request. Closes #20417
This commit is contained in:
parent
63822c2745
commit
7dc1c3349d
|
@ -117,13 +117,20 @@ public class RankEvalResponse extends ActionResponse implements ToXContent {
|
|||
builder.startObject("rank_eval");
|
||||
builder.field("spec_id", specId);
|
||||
builder.field("quality_level", qualityLevel);
|
||||
builder.startArray("unknown_docs");
|
||||
builder.startObject("unknown_docs");
|
||||
for (String key : unknownDocs.keySet()) {
|
||||
builder.startObject();
|
||||
builder.field(key, unknownDocs.get(key));
|
||||
builder.endObject();
|
||||
Collection<RatedDocumentKey> keys = unknownDocs.get(key);
|
||||
builder.startArray(key);
|
||||
for (RatedDocumentKey docKey : keys) {
|
||||
builder.startObject();
|
||||
builder.field(RatedDocument.INDEX_FIELD.getPreferredName(), docKey.getIndex());
|
||||
builder.field(RatedDocument.TYPE_FIELD.getPreferredName(), docKey.getType());
|
||||
builder.field(RatedDocument.DOC_ID_FIELD.getPreferredName(), docKey.getDocID());
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
builder.endArray();
|
||||
builder.endObject();
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ package org.elasticsearch.index.rankeval;
|
|||
import org.elasticsearch.action.support.ToXContentToBytes;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.ParseFieldMatcherSupplier;
|
||||
import org.elasticsearch.common.ParsingException;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
|
@ -39,41 +38,26 @@ import java.util.Objects;
|
|||
public class RatedDocument extends ToXContentToBytes implements Writeable {
|
||||
|
||||
public static final ParseField RATING_FIELD = new ParseField("rating");
|
||||
public static final ParseField KEY_FIELD = new ParseField("key");
|
||||
public static final ParseField DOC_ID_FIELD = new ParseField("doc_id");
|
||||
public static final ParseField TYPE_FIELD = new ParseField("type");
|
||||
public static final ParseField INDEX_FIELD = new ParseField("index");
|
||||
|
||||
private static final ConstructingObjectParser<RatedDocument, ParseFieldMatcherSupplier> PARSER =
|
||||
new ConstructingObjectParser<>("rated_document",
|
||||
a -> new RatedDocument((RatedDocumentKey) a[0], (Integer) a[1]));
|
||||
|
||||
new ConstructingObjectParser<>("rated_document",
|
||||
a -> new RatedDocument((String) a[0], (String) a[1], (String) a[2], (Integer) a[3]));
|
||||
|
||||
static {
|
||||
PARSER.declareObject(ConstructingObjectParser.constructorArg(), (p, c) -> {
|
||||
try {
|
||||
return RatedDocumentKey.fromXContent(p, c);
|
||||
} catch (IOException ex) {
|
||||
throw new ParsingException(p.getTokenLocation(), "error parsing rank request", ex);
|
||||
}
|
||||
} , KEY_FIELD);
|
||||
PARSER.declareString(ConstructingObjectParser.constructorArg(), INDEX_FIELD);
|
||||
PARSER.declareString(ConstructingObjectParser.constructorArg(), TYPE_FIELD);
|
||||
PARSER.declareString(ConstructingObjectParser.constructorArg(), DOC_ID_FIELD);
|
||||
PARSER.declareInt(ConstructingObjectParser.constructorArg(), RATING_FIELD);
|
||||
}
|
||||
|
||||
private RatedDocumentKey key;
|
||||
private int rating;
|
||||
private RatedDocumentKey key;
|
||||
|
||||
void setRatedDocumentKey(RatedDocumentKey key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
void setKey(RatedDocumentKey key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
void setRating(int rating) {
|
||||
this.rating = rating;
|
||||
}
|
||||
|
||||
public RatedDocument(RatedDocumentKey key, int rating) {
|
||||
this.key = key;
|
||||
this.rating = rating;
|
||||
public RatedDocument(String index, String type, String docId, int rating) {
|
||||
this(new RatedDocumentKey(index, type, docId), rating);
|
||||
}
|
||||
|
||||
public RatedDocument(StreamInput in) throws IOException {
|
||||
|
@ -81,10 +65,27 @@ public class RatedDocument extends ToXContentToBytes implements Writeable {
|
|||
this.rating = in.readVInt();
|
||||
}
|
||||
|
||||
public RatedDocument(RatedDocumentKey ratedDocumentKey, int rating) {
|
||||
this.key = ratedDocumentKey;
|
||||
this.rating = rating;
|
||||
}
|
||||
|
||||
public RatedDocumentKey getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public String getIndex() {
|
||||
return key.getIndex();
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return key.getType();
|
||||
}
|
||||
|
||||
public String getDocID() {
|
||||
return key.getDocID();
|
||||
}
|
||||
|
||||
public int getRating() {
|
||||
return rating;
|
||||
}
|
||||
|
@ -98,11 +99,13 @@ public class RatedDocument extends ToXContentToBytes implements Writeable {
|
|||
public static RatedDocument fromXContent(XContentParser parser, ParseFieldMatcherSupplier supplier) throws IOException {
|
||||
return PARSER.apply(parser, supplier);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
builder.field(KEY_FIELD.getPreferredName(), key);
|
||||
builder.field(INDEX_FIELD.getPreferredName(), key.getIndex());
|
||||
builder.field(TYPE_FIELD.getPreferredName(), key.getType());
|
||||
builder.field(DOC_ID_FIELD.getPreferredName(), key.getDocID());
|
||||
builder.field(RATING_FIELD.getPreferredName(), rating);
|
||||
builder.endObject();
|
||||
return builder;
|
||||
|
@ -120,7 +123,7 @@ public class RatedDocument extends ToXContentToBytes implements Writeable {
|
|||
return Objects.equals(key, other.key) &&
|
||||
Objects.equals(rating, other.rating);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
return Objects.hash(key, rating);
|
||||
|
|
|
@ -19,45 +19,15 @@
|
|||
|
||||
package org.elasticsearch.index.rankeval;
|
||||
|
||||
import org.elasticsearch.action.support.ToXContentToBytes;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.ParseFieldMatcherSupplier;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
public class RatedDocumentKey extends ToXContentToBytes implements Writeable {
|
||||
public static final ParseField DOC_ID_FIELD = new ParseField("doc_id");
|
||||
public static final ParseField TYPE_FIELD = new ParseField("type");
|
||||
public static final ParseField INDEX_FIELD = new ParseField("index");
|
||||
public class RatedDocumentKey implements Writeable {
|
||||
|
||||
private static final ConstructingObjectParser<RatedDocumentKey, ParseFieldMatcherSupplier> PARSER =
|
||||
new ConstructingObjectParser<>("ratings",
|
||||
a -> new RatedDocumentKey((String) a[0], (String) a[1], (String) a[2]));
|
||||
|
||||
static {
|
||||
PARSER.declareString(ConstructingObjectParser.constructorArg(), INDEX_FIELD);
|
||||
PARSER.declareString(ConstructingObjectParser.constructorArg(), TYPE_FIELD);
|
||||
PARSER.declareString(ConstructingObjectParser.constructorArg(), DOC_ID_FIELD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
builder.field(INDEX_FIELD.getPreferredName(), index);
|
||||
builder.field(TYPE_FIELD.getPreferredName(), type);
|
||||
builder.field(DOC_ID_FIELD.getPreferredName(), docId);
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
// TODO instead of docId use path to id and id itself
|
||||
private String docId;
|
||||
private String type;
|
||||
private String index;
|
||||
|
@ -69,7 +39,7 @@ public class RatedDocumentKey extends ToXContentToBytes implements Writeable {
|
|||
void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
void setDocId(String docId) {
|
||||
this.docId = docId;
|
||||
}
|
||||
|
@ -105,11 +75,6 @@ public class RatedDocumentKey extends ToXContentToBytes implements Writeable {
|
|||
out.writeString(docId);
|
||||
}
|
||||
|
||||
public static RatedDocumentKey fromXContent(
|
||||
XContentParser parser, ParseFieldMatcherSupplier context) throws IOException {
|
||||
return PARSER.apply(parser, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
|
@ -123,7 +88,7 @@ public class RatedDocumentKey extends ToXContentToBytes implements Writeable {
|
|||
Objects.equals(type, other.type) &&
|
||||
Objects.equals(docId, other.docId);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
return Objects.hash(index, type, docId);
|
||||
|
|
|
@ -69,7 +69,7 @@ import static org.elasticsearch.rest.RestRequest.Method.POST;
|
|||
"requests": [{
|
||||
"id": "amsterdam_query",
|
||||
"request": {
|
||||
"query": {
|
||||
"query": {
|
||||
"bool": {
|
||||
"must": [
|
||||
{"match": {"beverage": "coffee"}},
|
||||
|
@ -78,15 +78,12 @@ import static org.elasticsearch.rest.RestRequest.Method.POST;
|
|||
{"term": {"ip_location": {"value": "ams","boost": 10}}}]}
|
||||
},
|
||||
"size": 10
|
||||
}
|
||||
},
|
||||
"ratings": {
|
||||
"1": 1,
|
||||
"2": 0,
|
||||
"3": 1,
|
||||
"4": 1
|
||||
}
|
||||
}
|
||||
"ratings": [
|
||||
{\"index\": \"test\", \"type\": \"my_type\", \"doc_id\": \"1\", \"rating\" : 1 },
|
||||
{\"index\": \"test\", \"type\": \"my_type\", \"doc_id\": \"2\", \"rating\" : 0 },
|
||||
{\"index\": \"test\", \"type\": \"my_type\", \"doc_id\": \"3\", \"rating\" : 1 }
|
||||
]
|
||||
}, {
|
||||
"id": "berlin_query",
|
||||
"request": {
|
||||
|
@ -99,13 +96,8 @@ import static org.elasticsearch.rest.RestRequest.Method.POST;
|
|||
{"term": {"ip_location": {"value": "ber","boost": 10}}}]}
|
||||
},
|
||||
"size": 10
|
||||
}
|
||||
},
|
||||
"ratings": {
|
||||
"1": 0,
|
||||
"5": 1,
|
||||
"6": 1
|
||||
}
|
||||
"ratings": [ ... ]
|
||||
}],
|
||||
"metric": {
|
||||
"precisionAtN": {
|
||||
|
@ -129,7 +121,7 @@ import static org.elasticsearch.rest.RestRequest.Method.POST;
|
|||
"failed": 0
|
||||
},
|
||||
"quality_level": ... quality level ...,
|
||||
"unknown_docs": [{"user_request_id": [... list of unknown docs ...]}]
|
||||
"unknown_docs": {"user_request_id": [... list of unknown docs ...]}
|
||||
}
|
||||
|
||||
*
|
||||
|
@ -148,11 +140,17 @@ import static org.elasticsearch.rest.RestRequest.Method.POST;
|
|||
"rank_eval": [{
|
||||
"spec_id": "huge_weight_on_location",
|
||||
"quality_level": 0.4,
|
||||
"unknown_docs": [{
|
||||
"amsterdam_query": [5, 10, 23]
|
||||
"unknown_docs": {
|
||||
"amsterdam_query": [
|
||||
{ "index" : "test", "type" : "my_type", "doc_id" : "21"},
|
||||
{ "index" : "test", "type" : "my_type", "doc_id" : "5"},
|
||||
{ "index" : "test", "type" : "my_type", "doc_id" : "9"}
|
||||
]
|
||||
}, {
|
||||
"berlin_query": [42]
|
||||
}]
|
||||
"berlin_query": [
|
||||
{ "index" : "test", "type" : "my_type", "doc_id" : "42"}
|
||||
]
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
|
@ -189,8 +187,6 @@ public class RestRankEvalAction extends BaseRestHandler {
|
|||
client.execute(RankEvalAction.INSTANCE, rankEvalRequest, new RestToXContentListener<RankEvalResponse>(channel));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void parseRankEvalRequest(RankEvalRequest rankEvalRequest, RestRequest request, RankEvalContext context)
|
||||
throws IOException {
|
||||
List<String> indices = Arrays.asList(Strings.splitStringByCommaToArray(request.param("index")));
|
||||
|
|
|
@ -55,7 +55,7 @@ public class DiscountedCumulativeGainAtTests extends ESTestCase {
|
|||
int[] relevanceRatings = new int[] { 3, 2, 3, 0, 1, 2 };
|
||||
InternalSearchHit[] hits = new InternalSearchHit[6];
|
||||
for (int i = 0; i < 6; i++) {
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("index", "type", Integer.toString(i)), relevanceRatings[i]));
|
||||
rated.add(new RatedDocument("index", "type", Integer.toString(i), relevanceRatings[i]));
|
||||
hits[i] = new InternalSearchHit(i, Integer.toString(i), new Text("type"), Collections.emptyMap());
|
||||
hits[i].shard(new SearchShardTarget("testnode", new ShardId("index", "uuid", 0)));
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ public class DiscountedCumulativeGainAtTests extends ESTestCase {
|
|||
InternalSearchHit[] hits = new InternalSearchHit[6];
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (i < relevanceRatings.length) {
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("index", "type", Integer.toString(i)), relevanceRatings[i]));
|
||||
rated.add(new RatedDocument("index", "type", Integer.toString(i), relevanceRatings[i]));
|
||||
}
|
||||
hits[i] = new InternalSearchHit(i, Integer.toString(i), new Text("type"), Collections.emptyMap());
|
||||
hits[i].shard(new SearchShardTarget("testnode", new ShardId("index", "uuid", 0)));
|
||||
|
@ -121,7 +121,7 @@ public class DiscountedCumulativeGainAtTests extends ESTestCase {
|
|||
assertEquals(8, dcgAt.getPosition());
|
||||
assertEquals(true, dcgAt.getNormalize());
|
||||
}
|
||||
|
||||
|
||||
public static DiscountedCumulativeGainAt createTestItem() {
|
||||
int position = randomIntBetween(0, 1000);
|
||||
boolean normalize = randomBoolean();
|
||||
|
|
|
@ -42,7 +42,7 @@ public class PrecisionAtNTests extends ESTestCase {
|
|||
|
||||
public void testPrecisionAtFiveCalculation() throws IOException, InterruptedException, ExecutionException {
|
||||
List<RatedDocument> rated = new ArrayList<>();
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "0"), Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument("test", "testtype", "0", Rating.RELEVANT.ordinal()));
|
||||
InternalSearchHit[] hits = new InternalSearchHit[1];
|
||||
hits[0] = new InternalSearchHit(0, "0", new Text("testtype"), Collections.emptyMap());
|
||||
hits[0].shard(new SearchShardTarget("testnode", new Index("test", "uuid"), 0));
|
||||
|
@ -51,11 +51,11 @@ public class PrecisionAtNTests extends ESTestCase {
|
|||
|
||||
public void testPrecisionAtFiveIgnoreOneResult() throws IOException, InterruptedException, ExecutionException {
|
||||
List<RatedDocument> rated = new ArrayList<>();
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "0"), Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "1"), Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "2"), Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "3"), Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "4"), Rating.IRRELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument("test", "testtype", "0", Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument("test", "testtype", "1", Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument("test", "testtype", "2", Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument("test", "testtype", "3", Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument("test", "testtype", "4", Rating.IRRELEVANT.ordinal()));
|
||||
InternalSearchHit[] hits = new InternalSearchHit[5];
|
||||
for (int i = 0; i < 5; i++) {
|
||||
hits[i] = new InternalSearchHit(i, i+"", new Text("testtype"), Collections.emptyMap());
|
||||
|
@ -70,11 +70,11 @@ public class PrecisionAtNTests extends ESTestCase {
|
|||
*/
|
||||
public void testPrecisionAtFiveRelevanceThreshold() throws IOException, InterruptedException, ExecutionException {
|
||||
List<RatedDocument> rated = new ArrayList<>();
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "0"), 0));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "1"), 1));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "2"), 2));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "3"), 3));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "4"), 4));
|
||||
rated.add(new RatedDocument("test", "testtype", "0", 0));
|
||||
rated.add(new RatedDocument("test", "testtype", "1", 1));
|
||||
rated.add(new RatedDocument("test", "testtype", "2", 2));
|
||||
rated.add(new RatedDocument("test", "testtype", "3", 3));
|
||||
rated.add(new RatedDocument("test", "testtype", "4", 4));
|
||||
InternalSearchHit[] hits = new InternalSearchHit[5];
|
||||
for (int i = 0; i < 5; i++) {
|
||||
hits[i] = new InternalSearchHit(i, i+"", new Text("testtype"), Collections.emptyMap());
|
||||
|
@ -87,11 +87,11 @@ public class PrecisionAtNTests extends ESTestCase {
|
|||
|
||||
public void testPrecisionAtFiveCorrectIndex() throws IOException, InterruptedException, ExecutionException {
|
||||
List<RatedDocument> rated = new ArrayList<>();
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test_other", "testtype", "0"), Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test_other", "testtype", "1"), Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "2"), Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "3"), Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "4"), Rating.IRRELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument("test_other", "testtype", "0", Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument("test_other", "testtype", "1", Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument("test", "testtype", "2", Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument("test", "testtype", "3", Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument("test", "testtype", "4", Rating.IRRELEVANT.ordinal()));
|
||||
InternalSearchHit[] hits = new InternalSearchHit[5];
|
||||
for (int i = 0; i < 5; i++) {
|
||||
hits[i] = new InternalSearchHit(i, i+"", new Text("testtype"), Collections.emptyMap());
|
||||
|
@ -102,11 +102,11 @@ public class PrecisionAtNTests extends ESTestCase {
|
|||
|
||||
public void testPrecisionAtFiveCorrectType() throws IOException, InterruptedException, ExecutionException {
|
||||
List<RatedDocument> rated = new ArrayList<>();
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "other_type", "0"), Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "other_type", "1"), Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "2"), Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "3"), Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "4"), Rating.IRRELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument("test", "other_type", "0", Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument("test", "other_type", "1", Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument("test", "testtype", "2", Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument("test", "testtype", "3", Rating.RELEVANT.ordinal()));
|
||||
rated.add(new RatedDocument("test", "testtype", "4", Rating.IRRELEVANT.ordinal()));
|
||||
InternalSearchHit[] hits = new InternalSearchHit[5];
|
||||
for (int i = 0; i < 5; i++) {
|
||||
hits[i] = new InternalSearchHit(i, i+"", new Text("testtype"), Collections.emptyMap());
|
||||
|
|
|
@ -125,7 +125,7 @@ public class RankEvalRequestTests extends ESIntegTestCase {
|
|||
private static List<RatedDocument> createRelevant(String... docs) {
|
||||
List<RatedDocument> relevant = new ArrayList<>();
|
||||
for (String doc : docs) {
|
||||
relevant.add(new RatedDocument(new RatedDocumentKey("test", "testtype", doc), Rating.RELEVANT.ordinal()));
|
||||
relevant.add(new RatedDocument("test", "testtype", doc, Rating.RELEVANT.ordinal()));
|
||||
}
|
||||
return relevant;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,10 @@ package org.elasticsearch.index.rankeval;
|
|||
|
||||
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -61,4 +65,14 @@ public class RankEvalResponseTests extends ESTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testToXContent() throws IOException {
|
||||
RankEvalResponse randomResponse = createRandomResponse();
|
||||
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
|
||||
if (ESTestCase.randomBoolean()) {
|
||||
builder.prettyPrint();
|
||||
}
|
||||
builder.startObject();
|
||||
randomResponse.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
||||
builder.endObject();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,24 +19,49 @@
|
|||
|
||||
package org.elasticsearch.index.rankeval;
|
||||
|
||||
import org.elasticsearch.common.ParseFieldMatcher;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
||||
public class RatedDocumentKeyTests extends ESTestCase {
|
||||
|
||||
public void testXContentRoundtrip() throws IOException {
|
||||
public void testEqualsAndHash() throws IOException {
|
||||
String index = randomAsciiOfLengthBetween(0, 10);
|
||||
String type = randomAsciiOfLengthBetween(0, 10);
|
||||
String docId = randomAsciiOfLengthBetween(0, 10);
|
||||
|
||||
RatedDocumentKey testItem = new RatedDocumentKey(index, type, docId);
|
||||
XContentParser itemParser = XContentTestHelper.roundtrip(testItem);
|
||||
RatedDocumentKey parsedItem = RatedDocumentKey.fromXContent(itemParser, () -> ParseFieldMatcher.STRICT);
|
||||
assertNotSame(testItem, parsedItem);
|
||||
assertEquals(testItem, parsedItem);
|
||||
assertEquals(testItem.hashCode(), parsedItem.hashCode());
|
||||
|
||||
assertFalse("key is equal to null", testItem.equals(null));
|
||||
assertFalse("key is equal to incompatible type", testItem.equals(""));
|
||||
assertTrue("key is not equal to self", testItem.equals(testItem));
|
||||
assertThat("same key's hashcode returns different values if called multiple times", testItem.hashCode(),
|
||||
equalTo(testItem.hashCode()));
|
||||
|
||||
RatedDocumentKey mutation;
|
||||
switch (randomIntBetween(0, 2)) {
|
||||
case 0:
|
||||
mutation = new RatedDocumentKey(testItem.getIndex() + "_foo", testItem.getType(), testItem.getDocID());
|
||||
break;
|
||||
case 1:
|
||||
mutation = new RatedDocumentKey(testItem.getIndex(), testItem.getType() + "_foo", testItem.getDocID());
|
||||
break;
|
||||
case 2:
|
||||
mutation = new RatedDocumentKey(testItem.getIndex(), testItem.getType(), testItem.getDocID() + "_foo");
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("The test should only allow three parameters mutated");
|
||||
}
|
||||
|
||||
assertThat("different keys should not be equal", mutation, not(equalTo(testItem)));
|
||||
|
||||
RatedDocumentKey secondEqualKey = new RatedDocumentKey(index, type, docId);
|
||||
assertTrue("key is not equal to its copy", testItem.equals(secondEqualKey));
|
||||
assertTrue("equals is not symmetric", secondEqualKey.equals(testItem));
|
||||
assertThat("key copy's hashcode is different from original hashcode", secondEqualKey.hashCode(),
|
||||
equalTo(testItem.hashCode()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public class RatedDocumentTests extends ESTestCase {
|
|||
String docId = randomAsciiOfLength(10);
|
||||
int rating = randomInt();
|
||||
|
||||
return new RatedDocument(new RatedDocumentKey(index, type, docId), rating);
|
||||
return new RatedDocument(index, type, docId, rating);
|
||||
}
|
||||
|
||||
public void testXContentParsing() throws IOException {
|
||||
|
|
|
@ -112,6 +112,7 @@ public class RatedRequestsTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testParseFromXContent() throws IOException {
|
||||
// we modify the order of index/type/docId to make sure it doesn't matter for parsing xContent
|
||||
String querySpecString = " {\n"
|
||||
+ " \"id\": \"my_qa_query\",\n"
|
||||
+ " \"request\": {\n"
|
||||
|
@ -126,9 +127,9 @@ public class RatedRequestsTests extends ESTestCase {
|
|||
+ " \"size\": 10\n"
|
||||
+ " },\n"
|
||||
+ " \"ratings\": [ "
|
||||
+ " {\"key\": {\"index\": \"test\", \"type\": \"testtype\", \"doc_id\": \"1\"}, \"rating\" : 1 }, "
|
||||
+ " {\"key\": {\"index\": \"test\", \"type\": \"testtype\", \"doc_id\": \"2\"}, \"rating\" : 0 }, "
|
||||
+ " {\"key\": {\"index\": \"test\", \"type\": \"testtype\", \"doc_id\": \"3\"}, \"rating\" : 1 }]\n"
|
||||
+ " {\"index\": \"test\", \"type\": \"testtype\", \"doc_id\": \"1\", \"rating\" : 1 }, "
|
||||
+ " {\"type\": \"testtype\", \"index\": \"test\", \"doc_id\": \"2\", \"rating\" : 0 }, "
|
||||
+ " {\"doc_id\": \"3\", \"index\": \"test\", \"type\": \"testtype\", \"rating\" : 1 }]\n"
|
||||
+ "}";
|
||||
XContentParser parser = XContentFactory.xContent(querySpecString).createParser(querySpecString);
|
||||
QueryParseContext queryContext = new QueryParseContext(searchRequestParsers.queryParsers, parser, ParseFieldMatcher.STRICT);
|
||||
|
@ -139,13 +140,15 @@ public class RatedRequestsTests extends ESTestCase {
|
|||
assertNotNull(specification.getTestRequest());
|
||||
List<RatedDocument> ratedDocs = specification.getRatedDocs();
|
||||
assertEquals(3, ratedDocs.size());
|
||||
assertEquals("1", ratedDocs.get(0).getKey().getDocID());
|
||||
assertEquals(1, ratedDocs.get(0).getRating());
|
||||
assertEquals("2", ratedDocs.get(1).getKey().getDocID());
|
||||
assertEquals(0, ratedDocs.get(1).getRating());
|
||||
assertEquals("3", ratedDocs.get(2).getKey().getDocID());
|
||||
assertEquals(1, ratedDocs.get(2).getRating());
|
||||
for (int i = 0; i < 3; i++) {
|
||||
assertEquals("" + (i + 1), ratedDocs.get(i).getDocID());
|
||||
assertEquals("test", ratedDocs.get(i).getIndex());
|
||||
assertEquals("testtype", ratedDocs.get(i).getType());
|
||||
if (i == 1) {
|
||||
assertEquals(0, ratedDocs.get(i).getRating());
|
||||
} else {
|
||||
assertEquals(1, ratedDocs.get(i).getRating());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -56,13 +56,9 @@ public class ReciprocalRankTests extends ESTestCase {
|
|||
int relevantAt = 5;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (i == relevantAt) {
|
||||
ratedDocs.add(new RatedDocument(
|
||||
new RatedDocumentKey("test", "type", Integer.toString(i)),
|
||||
Rating.RELEVANT.ordinal()));
|
||||
ratedDocs.add(new RatedDocument("test", "type", Integer.toString(i), Rating.RELEVANT.ordinal()));
|
||||
} else {
|
||||
ratedDocs.add(new RatedDocument(
|
||||
new RatedDocumentKey("test", "type", Integer.toString(i)),
|
||||
Rating.IRRELEVANT.ordinal()));
|
||||
ratedDocs.add(new RatedDocument("test", "type", Integer.toString(i), Rating.IRRELEVANT.ordinal()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,13 +89,9 @@ public class ReciprocalRankTests extends ESTestCase {
|
|||
int relevantAt = randomIntBetween(0, 9);
|
||||
for (int i = 0; i <= 20; i++) {
|
||||
if (i == relevantAt) {
|
||||
ratedDocs.add(new RatedDocument(
|
||||
new RatedDocumentKey("test", "type", Integer.toString(i)),
|
||||
Rating.RELEVANT.ordinal()));
|
||||
ratedDocs.add(new RatedDocument("test", "type", Integer.toString(i), Rating.RELEVANT.ordinal()));
|
||||
} else {
|
||||
ratedDocs.add(new RatedDocument(
|
||||
new RatedDocumentKey("test", "type", Integer.toString(i)),
|
||||
Rating.IRRELEVANT.ordinal()));
|
||||
ratedDocs.add(new RatedDocument("test", "type", Integer.toString(i), Rating.IRRELEVANT.ordinal()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,11 +106,11 @@ public class ReciprocalRankTests extends ESTestCase {
|
|||
*/
|
||||
public void testPrecisionAtFiveRelevanceThreshold() throws IOException, InterruptedException, ExecutionException {
|
||||
List<RatedDocument> rated = new ArrayList<>();
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "0"), 0));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "1"), 1));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "2"), 2));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "3"), 3));
|
||||
rated.add(new RatedDocument(new RatedDocumentKey("test", "testtype", "4"), 4));
|
||||
rated.add(new RatedDocument("test", "testtype", "0", 0));
|
||||
rated.add(new RatedDocument("test", "testtype", "1", 1));
|
||||
rated.add(new RatedDocument("test", "testtype", "2", 2));
|
||||
rated.add(new RatedDocument("test", "testtype", "3", 3));
|
||||
rated.add(new RatedDocument("test", "testtype", "4", 4));
|
||||
InternalSearchHit[] hits = new InternalSearchHit[5];
|
||||
for (int i = 0; i < 5; i++) {
|
||||
hits[i] = new InternalSearchHit(i, i+"", new Text("testtype"), Collections.emptyMap());
|
||||
|
|
|
@ -47,14 +47,14 @@
|
|||
"id": "amsterdam_query",
|
||||
"request": { "query": { "match" : {"text" : "amsterdam" }}},
|
||||
"ratings": [
|
||||
{"key": { "index": "foo", "type": "bar", "doc_id": "doc1"}, "rating": 0},
|
||||
{"key": { "index": "foo", "type": "bar", "doc_id": "doc2"}, "rating": 1},
|
||||
{"key": { "index": "foo", "type": "bar", "doc_id": "doc3"}, "rating": 1}]
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc1", "rating": 0},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc2", "rating": 1},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc3", "rating": 1}]
|
||||
},
|
||||
{
|
||||
"id" : "berlin_query",
|
||||
"request": { "query": { "match" : { "text" : "berlin" } }, "size" : 10 },
|
||||
"ratings": [{"key": {"index": "foo", "type": "bar", "doc_id": "doc1"}, "rating": 1}]
|
||||
"ratings": [{"index": "foo", "type": "bar", "doc_id": "doc1", "rating": 1}]
|
||||
}
|
||||
],
|
||||
"metric" : { "precisionatn": { "size": 10}}
|
||||
|
@ -62,8 +62,8 @@
|
|||
|
||||
- match: {rank_eval.spec_id: "cities_qa_queries"}
|
||||
- match: {rank_eval.quality_level: 1}
|
||||
- match: {rank_eval.unknown_docs.0.amsterdam_query: [ {"index": "foo", "type": "bar", "doc_id": "doc4"}]}
|
||||
- match: {rank_eval.unknown_docs.1.berlin_query: [ {"index": "foo", "type": "bar", "doc_id": "doc4"}]}
|
||||
- match: {rank_eval.unknown_docs.amsterdam_query: [ {"index": "foo", "type": "bar", "doc_id": "doc4"}]}
|
||||
- match: {rank_eval.unknown_docs.berlin_query: [ {"index": "foo", "type": "bar", "doc_id": "doc4"}]}
|
||||
---
|
||||
"Reciprocal Rank":
|
||||
|
||||
|
@ -114,13 +114,13 @@
|
|||
"id": "amsterdam_query",
|
||||
"request": { "query": { "match" : {"text" : "amsterdam" }}},
|
||||
# doc4 should be returned in third position, so reciprocal rank is 1/3
|
||||
"ratings": [{"key": {"index": "foo", "type": "bar", "doc_id": "doc4"}, "rating": 1}]
|
||||
"ratings": [{"index": "foo", "type": "bar", "doc_id": "doc4", "rating": 1}]
|
||||
},
|
||||
{
|
||||
"id" : "berlin_query",
|
||||
"request": { "query": { "match" : { "text" : "berlin" } }, "size" : 10 },
|
||||
# doc1 should be returned in first position, doc3 in second, so reciprocal rank is 1/2
|
||||
"ratings": [{"key": {"index": "foo", "type": "bar", "doc_id": "doc4"}, "rating": 1}]
|
||||
"ratings": [{"index": "foo", "type": "bar", "doc_id": "doc4", "rating": 1}]
|
||||
}
|
||||
],
|
||||
"metric" : { "reciprocal_rank": {} }
|
||||
|
@ -139,13 +139,13 @@
|
|||
"id": "amsterdam_query",
|
||||
"request": { "query": { "match" : {"text" : "amsterdam" }}},
|
||||
# doc4 should be returned in third position, so reciprocal rank is 1/3
|
||||
"ratings": [{"key": {"index": "foo", "type": "bar", "doc_id": "doc4"}, "rating": 1}]
|
||||
"ratings": [{"index": "foo", "type": "bar", "doc_id": "doc4", "rating": 1}]
|
||||
},
|
||||
{
|
||||
"id" : "berlin_query",
|
||||
"request": { "query": { "match" : { "text" : "berlin" } }, "size" : 10 },
|
||||
# doc1 should be returned in first position, doc3 in second, so reciprocal rank is 1/2
|
||||
"ratings": [{"key": {"index": "foo", "type": "bar", "doc_id": "doc4"}, "rating": 1}]
|
||||
"ratings": [{"index": "foo", "type": "bar", "doc_id": "doc4", "rating": 1}]
|
||||
}
|
||||
],
|
||||
"metric" : {
|
||||
|
|
|
@ -53,12 +53,12 @@
|
|||
"id": "dcg_query",
|
||||
"request": { "query": { "match_all" : {}}, "sort" : [ "bar" ] },
|
||||
"ratings": [
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc1"}, "rating": 3},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc2"}, "rating": 2},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc3"}, "rating": 3},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc4"}, "rating": 0},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc5"}, "rating": 1},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc6"}, "rating": 2}]
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc1", "rating": 3},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc2", "rating": 2},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc3", "rating": 3},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc4", "rating": 0},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc5", "rating": 1},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc6", "rating": 2}]
|
||||
}
|
||||
],
|
||||
"metric" : { "dcg_at_n": { "size": 6}}
|
||||
|
@ -78,12 +78,12 @@
|
|||
"id": "dcg_query_reverse",
|
||||
"request": { "query": { "match_all" : {}}, "sort" : [ {"bar" : "desc" }] },
|
||||
"ratings": [
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc1"}, "rating": 3},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc2"}, "rating": 2},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc3"}, "rating": 3},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc4"}, "rating": 0},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc5"}, "rating": 1},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc6"}, "rating": 2}]
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc1", "rating": 3},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc2", "rating": 2},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc3", "rating": 3},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc4", "rating": 0},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc5", "rating": 1},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc6", "rating": 2}]
|
||||
},
|
||||
],
|
||||
"metric" : { "dcg_at_n": { "size": 6}}
|
||||
|
@ -103,23 +103,23 @@
|
|||
"id": "dcg_query",
|
||||
"request": { "query": { "match_all" : {}}, "sort" : [ "bar" ] },
|
||||
"ratings": [
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc1"}, "rating": 3},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc2"}, "rating": 2},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc3"}, "rating": 3},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc4"}, "rating": 0},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc5"}, "rating": 1},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc6"}, "rating": 2}]
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc1", "rating": 3},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc2", "rating": 2},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc3", "rating": 3},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc4", "rating": 0},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc5", "rating": 1},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc6", "rating": 2}]
|
||||
},
|
||||
{
|
||||
"id": "dcg_query_reverse",
|
||||
"request": { "query": { "match_all" : {}}, "sort" : [ {"bar" : "desc" }] },
|
||||
"ratings": [
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc1"}, "rating": 3},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc2"}, "rating": 2},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc3"}, "rating": 3},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc4"}, "rating": 0},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc5"}, "rating": 1},
|
||||
{"key": {"index": "foo", "type": "bar", "doc_id": "doc6"}, "rating": 2}]
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc1", "rating": 3},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc2", "rating": 2},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc3", "rating": 3},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc4", "rating": 0},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc5", "rating": 1},
|
||||
{"index": "foo", "type": "bar", "doc_id": "doc6", "rating": 2}]
|
||||
},
|
||||
],
|
||||
"metric" : { "dcg_at_n": { "size": 6}}
|
||||
|
|
Loading…
Reference in New Issue