Updating rank-eval module after major changes on master
This commit is contained in:
parent
4cb8d9d08c
commit
dde2a09ba5
|
@ -20,7 +20,6 @@
|
|||
package org.elasticsearch.index.rankeval;
|
||||
|
||||
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.xcontent.ObjectParser;
|
||||
|
@ -141,7 +140,7 @@ public class DiscountedCumulativeGain implements RankedListQualityMetric {
|
|||
|
||||
private static final ParseField NORMALIZE_FIELD = new ParseField("normalize");
|
||||
private static final ParseField UNKNOWN_DOC_RATING_FIELD = new ParseField("unknown_doc_rating");
|
||||
private static final ObjectParser<DiscountedCumulativeGain, ParseFieldMatcherSupplier> PARSER =
|
||||
private static final ObjectParser<DiscountedCumulativeGain, Void> PARSER =
|
||||
new ObjectParser<>("dcg_at", () -> new DiscountedCumulativeGain());
|
||||
|
||||
static {
|
||||
|
@ -149,8 +148,8 @@ public class DiscountedCumulativeGain implements RankedListQualityMetric {
|
|||
PARSER.declareInt(DiscountedCumulativeGain::setUnknownDocRating, UNKNOWN_DOC_RATING_FIELD);
|
||||
}
|
||||
|
||||
public static DiscountedCumulativeGain fromXContent(XContentParser parser, ParseFieldMatcherSupplier matcher) {
|
||||
return PARSER.apply(parser, matcher);
|
||||
public static DiscountedCumulativeGain fromXContent(XContentParser parser) {
|
||||
return PARSER.apply(parser, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
package org.elasticsearch.index.rankeval;
|
||||
|
||||
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.xcontent.ObjectParser;
|
||||
|
@ -49,7 +48,7 @@ public class Precision implements RankedListQualityMetric {
|
|||
|
||||
private static final ParseField RELEVANT_RATING_FIELD = new ParseField("relevant_rating_threshold");
|
||||
private static final ParseField IGNORE_UNLABELED_FIELD = new ParseField("ignore_unlabeled");
|
||||
private static final ObjectParser<Precision, ParseFieldMatcherSupplier> PARSER = new ObjectParser<>(NAME, Precision::new);
|
||||
private static final ObjectParser<Precision, Void> PARSER = new ObjectParser<>(NAME, Precision::new);
|
||||
|
||||
/**
|
||||
* This setting controls how unlabeled documents in the search hits are
|
||||
|
@ -118,8 +117,8 @@ public class Precision implements RankedListQualityMetric {
|
|||
return ignoreUnlabeled;
|
||||
}
|
||||
|
||||
public static Precision fromXContent(XContentParser parser, ParseFieldMatcherSupplier matcher) {
|
||||
return PARSER.apply(parser, matcher);
|
||||
public static Precision fromXContent(XContentParser parser) {
|
||||
return PARSER.apply(parser, null);
|
||||
}
|
||||
|
||||
/** Compute precisionAtN based on provided relevant document IDs.
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
* 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.common.ParseFieldMatcher;
|
||||
import org.elasticsearch.common.ParseFieldMatcherSupplier;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.query.QueryParseContext;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.search.SearchExtRegistry;
|
||||
import org.elasticsearch.search.SearchRequestParsers;
|
||||
import org.elasticsearch.search.aggregations.AggregatorParsers;
|
||||
import org.elasticsearch.search.suggest.Suggesters;
|
||||
|
||||
public class RankEvalContext implements ParseFieldMatcherSupplier {
|
||||
|
||||
private final SearchRequestParsers searchRequestParsers;
|
||||
private final ParseFieldMatcher parseFieldMatcher;
|
||||
private final QueryParseContext parseContext;
|
||||
private final ScriptService scriptService;
|
||||
|
||||
public RankEvalContext(ParseFieldMatcher parseFieldMatcher, QueryParseContext parseContext, SearchRequestParsers searchRequestParsers,
|
||||
ScriptService scriptService) {
|
||||
this.parseFieldMatcher = parseFieldMatcher;
|
||||
this.searchRequestParsers = searchRequestParsers;
|
||||
this.parseContext = parseContext;
|
||||
this.scriptService = scriptService;
|
||||
}
|
||||
|
||||
public Suggesters getSuggesters() {
|
||||
return searchRequestParsers.suggesters;
|
||||
}
|
||||
|
||||
public AggregatorParsers getAggs() {
|
||||
return searchRequestParsers.aggParsers;
|
||||
}
|
||||
|
||||
public SearchRequestParsers getSearchRequestParsers() {
|
||||
return searchRequestParsers;
|
||||
}
|
||||
|
||||
public ScriptService getScriptService() {
|
||||
return scriptService;
|
||||
}
|
||||
|
||||
public SearchExtRegistry getSearchExtParsers() {
|
||||
return searchRequestParsers.searchExtParsers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParseFieldMatcher getParseFieldMatcher() {
|
||||
return this.parseFieldMatcher;
|
||||
}
|
||||
|
||||
public XContentParser parser() {
|
||||
return this.parseContext.parser();
|
||||
}
|
||||
|
||||
public QueryParseContext getParseContext() {
|
||||
return this.parseContext;
|
||||
}
|
||||
|
||||
}
|
|
@ -21,15 +21,23 @@ package org.elasticsearch.index.rankeval;
|
|||
|
||||
import org.elasticsearch.action.ActionRequest;
|
||||
import org.elasticsearch.action.ActionResponse;
|
||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNodes;
|
||||
import org.elasticsearch.common.io.stream.NamedWriteable;
|
||||
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
|
||||
import org.elasticsearch.common.settings.ClusterSettings;
|
||||
import org.elasticsearch.common.settings.IndexScopedSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.settings.SettingsFilter;
|
||||
import org.elasticsearch.plugins.ActionPlugin;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.rest.RestHandler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class RankEvalPlugin extends Plugin implements ActionPlugin {
|
||||
|
||||
|
@ -38,9 +46,12 @@ public class RankEvalPlugin extends Plugin implements ActionPlugin {
|
|||
return Arrays.asList(new ActionHandler<>(RankEvalAction.INSTANCE, TransportRankEvalAction.class));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Class<? extends RestHandler>> getRestHandlers() {
|
||||
return Arrays.asList(RestRankEvalAction.class);
|
||||
public List<RestHandler> getRestHandlers(Settings settings, RestController restController, ClusterSettings clusterSettings,
|
||||
IndexScopedSettings indexScopedSettings, SettingsFilter settingsFilter, IndexNameExpressionResolver indexNameExpressionResolver,
|
||||
Supplier<DiscoveryNodes> nodesInCluster) {
|
||||
return Arrays.asList(new RestRankEvalAction(settings, restController));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,7 +23,7 @@ import org.elasticsearch.ElasticsearchException;
|
|||
import org.elasticsearch.action.ActionResponse;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -42,7 +42,7 @@ import java.util.Map;
|
|||
*
|
||||
**/
|
||||
//TODO instead of just returning averages over complete results, think of other statistics, micro avg, macro avg, partial results
|
||||
public class RankEvalResponse extends ActionResponse implements ToXContent {
|
||||
public class RankEvalResponse extends ActionResponse implements ToXContentObject {
|
||||
/**Average precision observed when issuing query intents with this specification.*/
|
||||
private double qualityLevel;
|
||||
/**Mapping from intent id to all documents seen for this intent that were not annotated.*/
|
||||
|
@ -113,6 +113,7 @@ public class RankEvalResponse extends ActionResponse implements ToXContent {
|
|||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
builder.startObject("rank_eval");
|
||||
builder.field("quality_level", qualityLevel);
|
||||
builder.startObject("details");
|
||||
|
@ -123,11 +124,12 @@ public class RankEvalResponse extends ActionResponse implements ToXContent {
|
|||
builder.startObject("failures");
|
||||
for (String key : failures.keySet()) {
|
||||
builder.startObject(key);
|
||||
ElasticsearchException.renderException(builder, params, failures.get(key));
|
||||
ElasticsearchException.generateFailureXContent(builder, params, failures.get(key), true);
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
builder.endObject();
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,37 +149,29 @@ public class RankEvalSpec extends ToXContentToBytes implements Writeable {
|
|||
private static final ParseField REQUESTS_FIELD = new ParseField("requests");
|
||||
private static final ParseField MAX_CONCURRENT_SEARCHES_FIELD = new ParseField("max_concurrent_searches");
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final ConstructingObjectParser<RankEvalSpec, RankEvalContext> PARSER =
|
||||
private static final ConstructingObjectParser<RankEvalSpec, Void> PARSER =
|
||||
new ConstructingObjectParser<>("rank_eval",
|
||||
a -> new RankEvalSpec((Collection<RatedRequest>) a[0], (RankedListQualityMetric) a[1], (Collection<ScriptWithId>) a[2]));
|
||||
|
||||
static {
|
||||
PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), (p, c) -> {
|
||||
try {
|
||||
return RatedRequest.fromXContent(p, c);
|
||||
} catch (IOException ex) {
|
||||
throw new ParsingException(p.getTokenLocation(), "error parsing rank request", ex);
|
||||
}
|
||||
return RatedRequest.fromXContent(p);
|
||||
} , REQUESTS_FIELD);
|
||||
PARSER.declareObject(ConstructingObjectParser.constructorArg(), (p, c) -> {
|
||||
try {
|
||||
return RankedListQualityMetric.fromXContent(p, c);
|
||||
return RankedListQualityMetric.fromXContent(p);
|
||||
} catch (IOException ex) {
|
||||
throw new ParsingException(p.getTokenLocation(), "error parsing rank request", ex);
|
||||
}
|
||||
} , METRIC_FIELD);
|
||||
PARSER.declareObjectArray(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> {
|
||||
try {
|
||||
return ScriptWithId.fromXContent(p, c);
|
||||
} catch (IOException ex) {
|
||||
throw new ParsingException(p.getTokenLocation(), "error parsing rank request", ex);
|
||||
}
|
||||
return ScriptWithId.fromXContent(p);
|
||||
}, TEMPLATES_FIELD);
|
||||
PARSER.declareInt(RankEvalSpec::setMaxConcurrentSearches, MAX_CONCURRENT_SEARCHES_FIELD);
|
||||
}
|
||||
|
||||
public static RankEvalSpec parse(XContentParser parser, RankEvalContext context) throws IOException {
|
||||
return PARSER.apply(parser, context);
|
||||
public static RankEvalSpec parse(XContentParser parser) {
|
||||
return PARSER.apply(parser, null);
|
||||
}
|
||||
|
||||
public static class ScriptWithId {
|
||||
|
@ -194,18 +186,18 @@ public class RankEvalSpec extends ToXContentToBytes implements Writeable {
|
|||
this.script = script;
|
||||
}
|
||||
|
||||
private static final ConstructingObjectParser<ScriptWithId, RankEvalContext> PARSER =
|
||||
private static final ConstructingObjectParser<ScriptWithId, Void> PARSER =
|
||||
new ConstructingObjectParser<>("script_with_id", a -> new ScriptWithId((String) a[0], (Script) a[1]));
|
||||
|
||||
public static ScriptWithId fromXContent(XContentParser parser, RankEvalContext context) throws IOException {
|
||||
return PARSER.apply(parser, context);
|
||||
public static ScriptWithId fromXContent(XContentParser parser) {
|
||||
return PARSER.apply(parser, null);
|
||||
}
|
||||
|
||||
static {
|
||||
PARSER.declareString(ConstructingObjectParser.constructorArg(), TEMPLATE_ID_FIELD);
|
||||
PARSER.declareObject(ConstructingObjectParser.constructorArg(), (p, c) -> {
|
||||
try {
|
||||
return Script.parse(p, c.getParseFieldMatcher(), "mustache");
|
||||
return Script.parse(p, "mustache");
|
||||
} catch (IOException ex) {
|
||||
throw new ParsingException(p.getTokenLocation(), "error parsing rank request", ex);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
package org.elasticsearch.index.rankeval;
|
||||
|
||||
import org.elasticsearch.common.ParseFieldMatcherSupplier;
|
||||
import org.elasticsearch.common.ParsingException;
|
||||
import org.elasticsearch.common.io.stream.NamedWriteable;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
|
@ -54,7 +53,7 @@ public interface RankedListQualityMetric extends ToXContent, NamedWriteable {
|
|||
* */
|
||||
EvalQueryQuality evaluate(String taskId, SearchHit[] hits, List<RatedDocument> ratedDocs);
|
||||
|
||||
static RankedListQualityMetric fromXContent(XContentParser parser, ParseFieldMatcherSupplier context) throws IOException {
|
||||
static RankedListQualityMetric fromXContent(XContentParser parser) throws IOException {
|
||||
RankedListQualityMetric rc;
|
||||
Token token = parser.nextToken();
|
||||
if (token != XContentParser.Token.FIELD_NAME) {
|
||||
|
@ -65,13 +64,13 @@ public interface RankedListQualityMetric extends ToXContent, NamedWriteable {
|
|||
// TODO maybe switch to using a plugable registry later?
|
||||
switch (metricName) {
|
||||
case Precision.NAME:
|
||||
rc = Precision.fromXContent(parser, context);
|
||||
rc = Precision.fromXContent(parser);
|
||||
break;
|
||||
case ReciprocalRank.NAME:
|
||||
rc = ReciprocalRank.fromXContent(parser, context);
|
||||
rc = ReciprocalRank.fromXContent(parser);
|
||||
break;
|
||||
case DiscountedCumulativeGain.NAME:
|
||||
rc = DiscountedCumulativeGain.fromXContent(parser, context);
|
||||
rc = DiscountedCumulativeGain.fromXContent(parser);
|
||||
break;
|
||||
default:
|
||||
throw new ParsingException(parser.getTokenLocation(), "[_na] unknown query metric name [{}]", metricName);
|
||||
|
|
|
@ -21,7 +21,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.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
|
@ -42,7 +41,7 @@ public class RatedDocument extends ToXContentToBytes implements Writeable {
|
|||
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 =
|
||||
private static final ConstructingObjectParser<RatedDocument, Void> PARSER =
|
||||
new ConstructingObjectParser<>("rated_document",
|
||||
a -> new RatedDocument((String) a[0], (String) a[1], (String) a[2], (Integer) a[3]));
|
||||
|
||||
|
@ -96,8 +95,8 @@ public class RatedDocument extends ToXContentToBytes implements Writeable {
|
|||
out.writeVInt(rating);
|
||||
}
|
||||
|
||||
public static RatedDocument fromXContent(XContentParser parser, ParseFieldMatcherSupplier supplier) throws IOException {
|
||||
return PARSER.apply(parser, supplier);
|
||||
public static RatedDocument fromXContent(XContentParser parser) {
|
||||
return PARSER.apply(parser, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -29,6 +29,7 @@ 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 org.elasticsearch.index.query.QueryParseContext;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -218,22 +219,18 @@ public class RatedRequest extends ToXContentToBytes implements Writeable {
|
|||
private static final ParseField FIELDS_FIELD = new ParseField("summary_fields");
|
||||
private static final ParseField TEMPLATE_ID_FIELD = new ParseField("template_id");
|
||||
|
||||
private static final ConstructingObjectParser<RatedRequest, RankEvalContext> PARSER =
|
||||
private static final ConstructingObjectParser<RatedRequest, QueryParseContext> PARSER =
|
||||
new ConstructingObjectParser<>("requests", a -> new RatedRequest(
|
||||
(String) a[0], (List<RatedDocument>) a[1], (SearchSourceBuilder) a[2], (Map<String, Object>) a[3], (String) a[4]));
|
||||
|
||||
static {
|
||||
PARSER.declareString(ConstructingObjectParser.constructorArg(), ID_FIELD);
|
||||
PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), (p, c) -> {
|
||||
try {
|
||||
return RatedDocument.fromXContent(p, c);
|
||||
} catch (IOException ex) {
|
||||
throw new ParsingException(p.getTokenLocation(), "error parsing ratings", ex);
|
||||
}
|
||||
return RatedDocument.fromXContent(p);
|
||||
}, RATINGS_FIELD);
|
||||
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> {
|
||||
try {
|
||||
return SearchSourceBuilder.fromXContent(c.getParseContext(), c.getAggs(), c.getSuggesters(), c.getSearchExtParsers());
|
||||
return SearchSourceBuilder.fromXContent(c);
|
||||
} catch (IOException ex) {
|
||||
throw new ParsingException(p.getTokenLocation(), "error parsing request", ex);
|
||||
}
|
||||
|
@ -270,8 +267,8 @@ public class RatedRequest extends ToXContentToBytes implements Writeable {
|
|||
* "ratings": [{ "1": 1 }, { "2": 0 }, { "3": 1 } ]
|
||||
* }
|
||||
*/
|
||||
public static RatedRequest fromXContent(XContentParser parser, RankEvalContext context) throws IOException {
|
||||
return PARSER.apply(parser, context);
|
||||
public static RatedRequest fromXContent(XContentParser parser) {
|
||||
return PARSER.apply(parser, new QueryParseContext(parser));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
package org.elasticsearch.index.rankeval;
|
||||
|
||||
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.xcontent.ObjectParser;
|
||||
|
@ -117,15 +116,15 @@ public class ReciprocalRank implements RankedListQualityMetric {
|
|||
}
|
||||
|
||||
private static final ParseField RELEVANT_RATING_FIELD = new ParseField("relevant_rating_threshold");
|
||||
private static final ObjectParser<ReciprocalRank, ParseFieldMatcherSupplier> PARSER = new ObjectParser<>(
|
||||
private static final ObjectParser<ReciprocalRank, Void> PARSER = new ObjectParser<>(
|
||||
"reciprocal_rank", () -> new ReciprocalRank());
|
||||
|
||||
static {
|
||||
PARSER.declareInt(ReciprocalRank::setRelevantRatingThreshhold, RELEVANT_RATING_FIELD);
|
||||
}
|
||||
|
||||
public static ReciprocalRank fromXContent(XContentParser parser, ParseFieldMatcherSupplier matcher) {
|
||||
return PARSER.apply(parser, matcher);
|
||||
public static ReciprocalRank fromXContent(XContentParser parser) {
|
||||
return PARSER.apply(parser, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,16 +21,12 @@ package org.elasticsearch.index.rankeval;
|
|||
|
||||
import org.elasticsearch.client.node.NodeClient;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.query.QueryParseContext;
|
||||
import org.elasticsearch.rest.BaseRestHandler;
|
||||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
import org.elasticsearch.rest.action.RestToXContentListener;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.search.SearchRequestParsers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
@ -154,18 +150,10 @@ import static org.elasticsearch.rest.RestRequest.Method.POST;
|
|||
|
||||
* */
|
||||
public class RestRankEvalAction extends BaseRestHandler {
|
||||
private SearchRequestParsers searchRequestParsers;
|
||||
private ScriptService scriptService;
|
||||
//private ScriptService scriptService;
|
||||
|
||||
@Inject
|
||||
public RestRankEvalAction(
|
||||
Settings settings,
|
||||
RestController controller,
|
||||
SearchRequestParsers searchRequestParsers,
|
||||
ScriptService scriptService) {
|
||||
public RestRankEvalAction(Settings settings, RestController controller) {
|
||||
super(settings);
|
||||
this.searchRequestParsers = searchRequestParsers;
|
||||
this.scriptService = scriptService;
|
||||
controller.registerHandler(GET, "/_rank_eval", this);
|
||||
controller.registerHandler(POST, "/_rank_eval", this);
|
||||
controller.registerHandler(GET, "/{index}/_rank_eval", this);
|
||||
|
@ -178,21 +166,17 @@ public class RestRankEvalAction extends BaseRestHandler {
|
|||
protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
|
||||
RankEvalRequest rankEvalRequest = new RankEvalRequest();
|
||||
try (XContentParser parser = request.contentOrSourceParamParser()) {
|
||||
QueryParseContext parseContext = new QueryParseContext(searchRequestParsers.queryParsers, parser, parseFieldMatcher);
|
||||
// TODO can we get rid of aggregators parsers and suggesters?
|
||||
parseRankEvalRequest(rankEvalRequest, request,
|
||||
new RankEvalContext(parseFieldMatcher, parseContext, searchRequestParsers, scriptService));
|
||||
parseRankEvalRequest(rankEvalRequest, request, parser);
|
||||
}
|
||||
return channel -> client.executeLocally(RankEvalAction.INSTANCE, rankEvalRequest,
|
||||
new RestToXContentListener<RankEvalResponse>(channel));
|
||||
}
|
||||
|
||||
public static void parseRankEvalRequest(RankEvalRequest rankEvalRequest, RestRequest request, RankEvalContext context)
|
||||
throws IOException {
|
||||
private static void parseRankEvalRequest(RankEvalRequest rankEvalRequest, RestRequest request, XContentParser parser) {
|
||||
List<String> indices = Arrays.asList(Strings.splitStringByCommaToArray(request.param("index")));
|
||||
List<String> types = Arrays.asList(Strings.splitStringByCommaToArray(request.param("type")));
|
||||
RankEvalSpec spec = null;
|
||||
spec = RankEvalSpec.parse(context.parser(), context);
|
||||
spec = RankEvalSpec.parse(parser);
|
||||
for (RatedRequest specification : spec.getRatedRequests()) {
|
||||
specification.setIndices(indices);
|
||||
specification.setTypes(types);
|
||||
|
|
|
@ -29,15 +29,15 @@ import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
|||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.index.query.QueryParseContext;
|
||||
import org.elasticsearch.script.CompiledScript;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptContext;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.search.SearchHit;
|
||||
import org.elasticsearch.search.SearchRequestParsers;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.transport.TransportService;
|
||||
|
@ -47,12 +47,14 @@ import java.util.Collection;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.XContentHelper.createParser;
|
||||
|
||||
/**
|
||||
* Instances of this class execute a collection of search intents (read: user supplied query parameters) against a set of
|
||||
* possible search requests (read: search specifications, expressed as query/search request templates) and compares the result
|
||||
|
@ -66,17 +68,17 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
public class TransportRankEvalAction extends HandledTransportAction<RankEvalRequest, RankEvalResponse> {
|
||||
private Client client;
|
||||
private ScriptService scriptService;
|
||||
private SearchRequestParsers searchRequestParsers;
|
||||
Queue<RequestTask> taskQueue = new ConcurrentLinkedQueue<>();
|
||||
private NamedXContentRegistry namedXContentRegistry;
|
||||
|
||||
@Inject
|
||||
public TransportRankEvalAction(Settings settings, ThreadPool threadPool, ActionFilters actionFilters,
|
||||
IndexNameExpressionResolver indexNameExpressionResolver, Client client, TransportService transportService,
|
||||
SearchRequestParsers searchRequestParsers, ScriptService scriptService) {
|
||||
ScriptService scriptService, NamedXContentRegistry namedXContentRegistry) {
|
||||
super(settings, RankEvalAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver,
|
||||
RankEvalRequest::new);
|
||||
this.searchRequestParsers = searchRequestParsers;
|
||||
this.scriptService = scriptService;
|
||||
this.namedXContentRegistry = namedXContentRegistry;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
|
@ -93,7 +95,7 @@ public class TransportRankEvalAction extends HandledTransportAction<RankEvalRequ
|
|||
for (Entry<String, Script> entry : qualityTask.getTemplates().entrySet()) {
|
||||
scriptsWithoutParams.put(
|
||||
entry.getKey(),
|
||||
scriptService.compile(entry.getValue(), ScriptContext.Standard.SEARCH, new HashMap<>()));
|
||||
scriptService.compile(entry.getValue(), ScriptContext.Standard.SEARCH));
|
||||
}
|
||||
|
||||
for (RatedRequest ratedRequest : ratedRequests) {
|
||||
|
@ -104,11 +106,10 @@ public class TransportRankEvalAction extends HandledTransportAction<RankEvalRequ
|
|||
Map<String, Object> params = ratedRequest.getParams();
|
||||
String templateId = ratedRequest.getTemplateId();
|
||||
CompiledScript compiled = scriptsWithoutParams.get(templateId);
|
||||
String resolvedRequest = ((BytesReference) (scriptService.executable(compiled, params).run())).utf8ToString();
|
||||
try (XContentParser subParser = XContentFactory.xContent(resolvedRequest).createParser(resolvedRequest)) {
|
||||
QueryParseContext parseContext = new QueryParseContext(searchRequestParsers.queryParsers, subParser, parseFieldMatcher);
|
||||
ratedSearchSource = SearchSourceBuilder.fromXContent(parseContext, searchRequestParsers.aggParsers,
|
||||
searchRequestParsers.suggesters, searchRequestParsers.searchExtParsers);
|
||||
BytesReference resolvedRequest = (BytesReference) (scriptService.executable(compiled, params).run());
|
||||
try (XContentParser subParser = createParser(namedXContentRegistry, resolvedRequest, XContentType.JSON)) {
|
||||
QueryParseContext parseContext = new QueryParseContext(subParser);
|
||||
ratedSearchSource = SearchSourceBuilder.fromXContent(parseContext);
|
||||
} catch (IOException e) {
|
||||
listener.onFailure(e);
|
||||
}
|
||||
|
@ -143,7 +144,7 @@ public class TransportRankEvalAction extends HandledTransportAction<RankEvalRequ
|
|||
public SearchRequest request;
|
||||
public RankEvalActionListener searchListener;
|
||||
|
||||
public RequestTask(SearchRequest request, RankEvalActionListener listener) {
|
||||
RequestTask(SearchRequest request, RankEvalActionListener listener) {
|
||||
this.request = request;
|
||||
this.searchListener = listener;
|
||||
}
|
||||
|
|
|
@ -19,10 +19,13 @@
|
|||
|
||||
package org.elasticsearch.index.rankeval;
|
||||
|
||||
import org.elasticsearch.common.ParseFieldMatcher;
|
||||
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.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||
import org.elasticsearch.index.shard.ShardId;
|
||||
import org.elasticsearch.search.SearchShardTarget;
|
||||
import org.elasticsearch.search.internal.InternalSearchHit;
|
||||
|
@ -192,10 +195,11 @@ public class DiscountedCumulativeGainTests extends ESTestCase {
|
|||
+ " \"unknown_doc_rating\": 2,\n"
|
||||
+ " \"normalize\": true\n"
|
||||
+ "}";
|
||||
XContentParser parser = XContentFactory.xContent(xContent).createParser(xContent);
|
||||
DiscountedCumulativeGain dcgAt = DiscountedCumulativeGain.fromXContent(parser, () -> ParseFieldMatcher.STRICT);
|
||||
assertEquals(2, dcgAt.getUnknownDocRating().intValue());
|
||||
assertEquals(true, dcgAt.getNormalize());
|
||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) {
|
||||
DiscountedCumulativeGain dcgAt = DiscountedCumulativeGain.fromXContent(parser);
|
||||
assertEquals(2, dcgAt.getUnknownDocRating().intValue());
|
||||
assertEquals(true, dcgAt.getNormalize());
|
||||
}
|
||||
}
|
||||
|
||||
public static DiscountedCumulativeGain createTestItem() {
|
||||
|
@ -206,13 +210,16 @@ public class DiscountedCumulativeGainTests extends ESTestCase {
|
|||
}
|
||||
public void testXContentRoundtrip() throws IOException {
|
||||
DiscountedCumulativeGain testItem = createTestItem();
|
||||
XContentParser itemParser = RankEvalTestHelper.roundtrip(testItem);
|
||||
itemParser.nextToken();
|
||||
itemParser.nextToken();
|
||||
DiscountedCumulativeGain parsedItem = DiscountedCumulativeGain.fromXContent(itemParser, () -> ParseFieldMatcher.STRICT);
|
||||
assertNotSame(testItem, parsedItem);
|
||||
assertEquals(testItem, parsedItem);
|
||||
assertEquals(testItem.hashCode(), parsedItem.hashCode());
|
||||
XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values()));
|
||||
XContentBuilder shuffled = shuffleXContent(testItem.toXContent(builder, ToXContent.EMPTY_PARAMS));
|
||||
try (XContentParser itemParser = createParser(shuffled)) {
|
||||
itemParser.nextToken();
|
||||
itemParser.nextToken();
|
||||
DiscountedCumulativeGain parsedItem = DiscountedCumulativeGain.fromXContent(itemParser);
|
||||
assertNotSame(testItem, parsedItem);
|
||||
assertEquals(testItem, parsedItem);
|
||||
assertEquals(testItem.hashCode(), parsedItem.hashCode());
|
||||
}
|
||||
}
|
||||
|
||||
public void testSerialization() throws IOException {
|
||||
|
|
|
@ -19,10 +19,13 @@
|
|||
|
||||
package org.elasticsearch.index.rankeval;
|
||||
|
||||
import org.elasticsearch.common.ParseFieldMatcher;
|
||||
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.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.search.SearchHit;
|
||||
import org.elasticsearch.search.SearchShardTarget;
|
||||
|
@ -153,9 +156,10 @@ public class PrecisionTests extends ESTestCase {
|
|||
String xContent = " {\n"
|
||||
+ " \"relevant_rating_threshold\" : 2"
|
||||
+ "}";
|
||||
XContentParser parser = XContentFactory.xContent(xContent).createParser(xContent);
|
||||
Precision precicionAt = Precision.fromXContent(parser, () -> ParseFieldMatcher.STRICT);
|
||||
assertEquals(2, precicionAt.getRelevantRatingThreshold());
|
||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, xContent)) {
|
||||
Precision precicionAt = Precision.fromXContent(parser);
|
||||
assertEquals(2, precicionAt.getRelevantRatingThreshold());
|
||||
}
|
||||
}
|
||||
|
||||
public void testCombine() {
|
||||
|
@ -183,13 +187,16 @@ public class PrecisionTests extends ESTestCase {
|
|||
|
||||
public void testXContentRoundtrip() throws IOException {
|
||||
Precision testItem = createTestItem();
|
||||
XContentParser itemParser = RankEvalTestHelper.roundtrip(testItem);
|
||||
itemParser.nextToken();
|
||||
itemParser.nextToken();
|
||||
Precision parsedItem = Precision.fromXContent(itemParser, () -> ParseFieldMatcher.STRICT);
|
||||
assertNotSame(testItem, parsedItem);
|
||||
assertEquals(testItem, parsedItem);
|
||||
assertEquals(testItem.hashCode(), parsedItem.hashCode());
|
||||
XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values()));
|
||||
XContentBuilder shuffled = shuffleXContent(testItem.toXContent(builder, ToXContent.EMPTY_PARAMS));
|
||||
try (XContentParser itemParser = createParser(shuffled)) {
|
||||
itemParser.nextToken();
|
||||
itemParser.nextToken();
|
||||
Precision parsedItem = Precision.fromXContent(itemParser);
|
||||
assertNotSame(testItem, parsedItem);
|
||||
assertEquals(testItem, parsedItem);
|
||||
assertEquals(testItem.hashCode(), parsedItem.hashCode());
|
||||
}
|
||||
}
|
||||
|
||||
public void testSerialization() throws IOException {
|
||||
|
|
|
@ -78,9 +78,7 @@ public class RankEvalResponseTests extends ESTestCase {
|
|||
if (ESTestCase.randomBoolean()) {
|
||||
builder.prettyPrint();
|
||||
}
|
||||
builder.startObject();
|
||||
randomResponse.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
||||
builder.endObject();
|
||||
// TODO check the correctness of the output
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,30 +19,19 @@
|
|||
|
||||
package org.elasticsearch.index.rankeval;
|
||||
|
||||
import org.elasticsearch.common.ParseFieldMatcher;
|
||||
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.ParseFieldRegistry;
|
||||
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.json.JsonXContent;
|
||||
import org.elasticsearch.index.query.MatchAllQueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryParseContext;
|
||||
import org.elasticsearch.index.rankeval.RankEvalSpec.ScriptWithId;
|
||||
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptType;
|
||||
import org.elasticsearch.search.SearchModule;
|
||||
import org.elasticsearch.search.SearchRequestParsers;
|
||||
import org.elasticsearch.search.aggregations.AggregatorParsers;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.search.suggest.Suggesters;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -56,30 +45,7 @@ import java.util.Map;
|
|||
import java.util.Map.Entry;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
|
||||
public class RankEvalSpecTests extends ESTestCase {
|
||||
private static SearchModule searchModule;
|
||||
private static SearchRequestParsers searchRequestParsers;
|
||||
|
||||
/**
|
||||
* setup for the whole base test class
|
||||
*/
|
||||
@BeforeClass
|
||||
public static void init() {
|
||||
AggregatorParsers aggsParsers = new AggregatorParsers(new ParseFieldRegistry<>("aggregation"),
|
||||
new ParseFieldRegistry<>("aggregation_pipes"));
|
||||
searchModule = new SearchModule(Settings.EMPTY, false, emptyList());
|
||||
IndicesQueriesRegistry queriesRegistry = searchModule.getQueryParserRegistry();
|
||||
Suggesters suggesters = searchModule.getSuggesters();
|
||||
searchRequestParsers = new SearchRequestParsers(queriesRegistry, aggsParsers, suggesters, null);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
searchModule = null;
|
||||
searchRequestParsers = null;
|
||||
}
|
||||
|
||||
private static <T> List<T> randomList(Supplier<T> randomSupplier) {
|
||||
List<T> result = new ArrayList<>();
|
||||
|
@ -90,7 +56,7 @@ public class RankEvalSpecTests extends ESTestCase {
|
|||
return result;
|
||||
}
|
||||
|
||||
private RankEvalSpec createTestItem() throws IOException {
|
||||
private static RankEvalSpec createTestItem() throws IOException {
|
||||
RankedListQualityMetric metric;
|
||||
if (randomBoolean()) {
|
||||
metric = PrecisionTests.createTestItem();
|
||||
|
@ -118,7 +84,7 @@ public class RankEvalSpecTests extends ESTestCase {
|
|||
|
||||
templates = new HashSet<>();
|
||||
templates.add(
|
||||
new ScriptWithId("templateId", new Script(scriptType, randomFrom("_lang1", "_lang2"), script, params)));
|
||||
new ScriptWithId("templateId", new Script(scriptType, Script.DEFAULT_TEMPLATE_LANG, script, params)));
|
||||
|
||||
Map<String, Object> templateParams = new HashMap<>();
|
||||
templateParams.put("key", "value");
|
||||
|
@ -138,19 +104,18 @@ public class RankEvalSpecTests extends ESTestCase {
|
|||
public void testXContentRoundtrip() throws IOException {
|
||||
RankEvalSpec testItem = createTestItem();
|
||||
|
||||
XContentBuilder shuffled = ESTestCase.shuffleXContent(testItem.toXContent(XContentFactory.jsonBuilder(), ToXContent.EMPTY_PARAMS));
|
||||
XContentParser itemParser = XContentHelper.createParser(shuffled.bytes());
|
||||
XContentBuilder shuffled = shuffleXContent(testItem.toXContent(XContentFactory.jsonBuilder(), ToXContent.EMPTY_PARAMS));
|
||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, shuffled.bytes())) {
|
||||
|
||||
QueryParseContext queryContext = new QueryParseContext(searchRequestParsers.queryParsers, itemParser, ParseFieldMatcher.STRICT);
|
||||
RankEvalContext rankContext = new RankEvalContext(ParseFieldMatcher.STRICT, queryContext,
|
||||
searchRequestParsers, null);
|
||||
|
||||
RankEvalSpec parsedItem = RankEvalSpec.parse(itemParser, rankContext);
|
||||
// IRL these come from URL parameters - see RestRankEvalAction
|
||||
// TODO Do we still need this? parsedItem.getRatedRequests().stream().forEach(e -> {e.setIndices(indices); e.setTypes(types);});
|
||||
assertNotSame(testItem, parsedItem);
|
||||
assertEquals(testItem, parsedItem);
|
||||
assertEquals(testItem.hashCode(), parsedItem.hashCode());
|
||||
RankEvalSpec parsedItem = RankEvalSpec.parse(parser);
|
||||
// IRL these come from URL parameters - see RestRankEvalAction
|
||||
// TODO Do we still need this?
|
||||
// parsedItem.getRatedRequests().stream().forEach(e ->
|
||||
// {e.setIndices(indices); e.setTypes(types);});
|
||||
assertNotSame(testItem, parsedItem);
|
||||
assertEquals(testItem, parsedItem);
|
||||
assertEquals(testItem.hashCode(), parsedItem.hashCode());
|
||||
}
|
||||
}
|
||||
|
||||
public void testSerialization() throws IOException {
|
||||
|
@ -185,7 +150,7 @@ public class RankEvalSpecTests extends ESTestCase {
|
|||
RankEvalTestHelper.copy(testItem, RankEvalSpec::new, new NamedWriteableRegistry(namedWriteables)));
|
||||
}
|
||||
|
||||
private RankEvalSpec mutateTestItem(RankEvalSpec mutant) {
|
||||
private static RankEvalSpec mutateTestItem(RankEvalSpec mutant) {
|
||||
Collection<RatedRequest> ratedRequests = mutant.getRatedRequests();
|
||||
RankedListQualityMetric metric = mutant.getMetric();
|
||||
Map<String, Script> templates = mutant.getTemplates();
|
||||
|
@ -193,7 +158,7 @@ public class RankEvalSpecTests extends ESTestCase {
|
|||
int mutate = randomIntBetween(0, 2);
|
||||
switch (mutate) {
|
||||
case 0:
|
||||
RatedRequest request = RatedRequestsTests.createTestItem(new ArrayList<>(), new ArrayList<>());
|
||||
RatedRequest request = RatedRequestsTests.createTestItem(new ArrayList<>(), new ArrayList<>(), true);
|
||||
ratedRequests.add(request);
|
||||
break;
|
||||
case 1:
|
||||
|
@ -205,13 +170,8 @@ public class RankEvalSpecTests extends ESTestCase {
|
|||
break;
|
||||
case 2:
|
||||
if (templates.size() > 0) {
|
||||
if (randomBoolean()) {
|
||||
templates = null;
|
||||
} else {
|
||||
String mutatedTemplate = randomAsciiOfLength(10);
|
||||
templates.put("mutation", new Script(ScriptType.INLINE, "mustache", mutatedTemplate, new HashMap<>()));
|
||||
|
||||
}
|
||||
String mutatedTemplate = randomAsciiOfLength(10);
|
||||
templates.put("mutation", new Script(ScriptType.INLINE, "mustache", mutatedTemplate, new HashMap<>()));
|
||||
} else {
|
||||
String mutatedTemplate = randomValueOtherThanMany(templates::containsValue, () -> randomAsciiOfLength(10));
|
||||
templates.put("mutation", new Script(ScriptType.INLINE, "mustache", mutatedTemplate, new HashMap<>()));
|
||||
|
@ -238,7 +198,7 @@ public class RankEvalSpecTests extends ESTestCase {
|
|||
|
||||
public void testMissingMetricFailsParsing() {
|
||||
List<String> strings = Arrays.asList("value");
|
||||
List<RatedRequest> ratedRequests = randomList(() -> RatedRequestsTests.createTestItem(strings, strings));
|
||||
List<RatedRequest> ratedRequests = randomList(() -> RatedRequestsTests.createTestItem(strings, strings, randomBoolean()));
|
||||
expectThrows(IllegalStateException.class, () -> new RankEvalSpec(ratedRequests, null));
|
||||
}
|
||||
|
||||
|
|
|
@ -25,13 +25,6 @@ import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput;
|
|||
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
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.util.Collections;
|
||||
|
@ -45,17 +38,6 @@ import static org.junit.Assert.assertTrue;
|
|||
|
||||
public class RankEvalTestHelper {
|
||||
|
||||
public static XContentParser roundtrip(ToXContent testItem) throws IOException {
|
||||
XContentBuilder builder = XContentFactory.contentBuilder(ESTestCase.randomFrom(XContentType.values()));
|
||||
if (ESTestCase.randomBoolean()) {
|
||||
builder.prettyPrint();
|
||||
}
|
||||
testItem.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
||||
XContentBuilder shuffled = ESTestCase.shuffleXContent(builder);
|
||||
XContentParser itemParser = XContentHelper.createParser(shuffled.bytes());
|
||||
return itemParser;
|
||||
}
|
||||
|
||||
public static <T> void testHashCodeAndEquals(T testItem, T mutation, T secondCopy) {
|
||||
assertFalse("testItem is equal to null", testItem.equals(null));
|
||||
assertFalse("testItem is equal to incompatible type", testItem.equals(""));
|
||||
|
|
|
@ -24,7 +24,6 @@ import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
|||
|
||||
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
||||
import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -34,7 +33,7 @@ public class RankEvalYamlIT extends ESClientYamlSuiteTestCase {
|
|||
}
|
||||
|
||||
@ParametersFactory
|
||||
public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
|
||||
public static Iterable<Object[]> parameters() throws IOException {
|
||||
return ESClientYamlSuiteTestCase.createParameters();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,11 @@
|
|||
|
||||
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.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -38,11 +41,14 @@ public class RatedDocumentTests extends ESTestCase {
|
|||
|
||||
public void testXContentParsing() throws IOException {
|
||||
RatedDocument testItem = createRatedDocument();
|
||||
XContentParser itemParser = RankEvalTestHelper.roundtrip(testItem);
|
||||
RatedDocument parsedItem = RatedDocument.fromXContent(itemParser, () -> ParseFieldMatcher.STRICT);
|
||||
assertNotSame(testItem, parsedItem);
|
||||
assertEquals(testItem, parsedItem);
|
||||
assertEquals(testItem.hashCode(), parsedItem.hashCode());
|
||||
XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values()));
|
||||
XContentBuilder shuffled = shuffleXContent(testItem.toXContent(builder, ToXContent.EMPTY_PARAMS));
|
||||
try (XContentParser itemParser = createParser(shuffled)) {
|
||||
RatedDocument parsedItem = RatedDocument.fromXContent(itemParser);
|
||||
assertNotSame(testItem, parsedItem);
|
||||
assertEquals(testItem, parsedItem);
|
||||
assertEquals(testItem.hashCode(), parsedItem.hashCode());
|
||||
}
|
||||
}
|
||||
|
||||
public void testSerialization() throws IOException {
|
||||
|
|
|
@ -19,21 +19,19 @@
|
|||
|
||||
package org.elasticsearch.index.rankeval;
|
||||
|
||||
import org.elasticsearch.common.ParseFieldMatcher;
|
||||
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.ParseFieldRegistry;
|
||||
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||
import org.elasticsearch.index.query.MatchAllQueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryParseContext;
|
||||
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
|
||||
import org.elasticsearch.search.SearchModule;
|
||||
import org.elasticsearch.search.SearchRequestParsers;
|
||||
import org.elasticsearch.search.aggregations.AggregatorParsers;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.search.suggest.Suggesters;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
|
@ -44,36 +42,38 @@ import java.util.Arrays;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
public class RatedRequestsTests extends ESTestCase {
|
||||
|
||||
private static SearchModule searchModule;
|
||||
private static SearchRequestParsers searchRequestParsers;
|
||||
private static NamedXContentRegistry xContentRegistry;
|
||||
|
||||
/**
|
||||
* setup for the whole base test class
|
||||
*/
|
||||
@BeforeClass
|
||||
public static void init() throws IOException {
|
||||
AggregatorParsers aggsParsers = new AggregatorParsers(new ParseFieldRegistry<>("aggregation"),
|
||||
new ParseFieldRegistry<>("aggregation_pipes"));
|
||||
searchModule = new SearchModule(Settings.EMPTY, false, emptyList());
|
||||
IndicesQueriesRegistry queriesRegistry = searchModule.getQueryParserRegistry();
|
||||
Suggesters suggesters = searchModule.getSuggesters();
|
||||
searchRequestParsers = new SearchRequestParsers(queriesRegistry, aggsParsers, suggesters, null);
|
||||
public static void init() {
|
||||
xContentRegistry = new NamedXContentRegistry(Stream.of(
|
||||
new SearchModule(Settings.EMPTY, false, emptyList()).getNamedXContents().stream()
|
||||
).flatMap(Function.identity()).collect(toList()));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
searchModule = null;
|
||||
searchRequestParsers = null;
|
||||
xContentRegistry = null;
|
||||
}
|
||||
|
||||
public static RatedRequest createTestItem(List<String> indices, List<String> types) {
|
||||
String requestId = randomAsciiOfLength(50);
|
||||
@Override
|
||||
protected NamedXContentRegistry xContentRegistry() {
|
||||
return xContentRegistry;
|
||||
}
|
||||
|
||||
public static RatedRequest createTestItem(List<String> indices, List<String> types, boolean forceRequest) {
|
||||
String requestId = randomAsciiOfLength(50);
|
||||
|
||||
List<RatedDocument> ratedDocs = new ArrayList<>();
|
||||
int size = randomIntBetween(0, 2);
|
||||
|
@ -83,15 +83,15 @@ public class RatedRequestsTests extends ESTestCase {
|
|||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
SearchSourceBuilder testRequest = null;
|
||||
if (randomBoolean()) {
|
||||
if (randomBoolean() || forceRequest) {
|
||||
testRequest = new SearchSourceBuilder();
|
||||
testRequest.size(randomInt());
|
||||
testRequest.query(new MatchAllQueryBuilder());
|
||||
} else {
|
||||
int randomSize = randomIntBetween(1, 10);
|
||||
for (int i = 0; i < randomSize; i++) {
|
||||
params.put(randomAsciiOfLengthBetween(1, 10), randomAsciiOfLengthBetween(1, 10));
|
||||
}
|
||||
} else {
|
||||
testRequest = new SearchSourceBuilder();
|
||||
testRequest.size(randomInt());
|
||||
testRequest.query(new MatchAllQueryBuilder());
|
||||
}
|
||||
|
||||
List<String> summaryFields = new ArrayList<>();
|
||||
|
@ -112,8 +112,6 @@ public class RatedRequestsTests extends ESTestCase {
|
|||
ratedRequest.setTypes(types);
|
||||
ratedRequest.setSummaryFields(summaryFields);
|
||||
}
|
||||
|
||||
|
||||
return ratedRequest;
|
||||
}
|
||||
|
||||
|
@ -130,20 +128,22 @@ public class RatedRequestsTests extends ESTestCase {
|
|||
types.add(randomAsciiOfLengthBetween(0, 50));
|
||||
}
|
||||
|
||||
RatedRequest testItem = createTestItem(indices, types);
|
||||
XContentParser itemParser = RankEvalTestHelper.roundtrip(testItem);
|
||||
itemParser.nextToken();
|
||||
RatedRequest testItem = createTestItem(indices, types, randomBoolean());
|
||||
XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values()));
|
||||
XContentBuilder shuffled = shuffleXContent(testItem.toXContent(builder, ToXContent.EMPTY_PARAMS));
|
||||
try (XContentParser itemParser = createParser(shuffled)) {
|
||||
itemParser.nextToken();
|
||||
|
||||
QueryParseContext queryContext = new QueryParseContext(searchRequestParsers.queryParsers, itemParser, ParseFieldMatcher.STRICT);
|
||||
RankEvalContext rankContext = new RankEvalContext(ParseFieldMatcher.STRICT, queryContext,
|
||||
searchRequestParsers, null);
|
||||
|
||||
RatedRequest parsedItem = RatedRequest.fromXContent(itemParser, rankContext);
|
||||
parsedItem.setIndices(indices); // IRL these come from URL parameters - see RestRankEvalAction
|
||||
parsedItem.setTypes(types); // IRL these come from URL parameters - see RestRankEvalAction
|
||||
assertNotSame(testItem, parsedItem);
|
||||
assertEquals(testItem, parsedItem);
|
||||
assertEquals(testItem.hashCode(), parsedItem.hashCode());
|
||||
RatedRequest parsedItem = RatedRequest.fromXContent(itemParser);
|
||||
parsedItem.setIndices(indices); // IRL these come from URL
|
||||
// parameters - see
|
||||
// RestRankEvalAction
|
||||
parsedItem.setTypes(types); // IRL these come from URL parameters -
|
||||
// see RestRankEvalAction
|
||||
assertNotSame(testItem, parsedItem);
|
||||
assertEquals(testItem, parsedItem);
|
||||
assertEquals(testItem.hashCode(), parsedItem.hashCode());
|
||||
}
|
||||
}
|
||||
|
||||
public void testSerialization() throws IOException {
|
||||
|
@ -159,7 +159,7 @@ public class RatedRequestsTests extends ESTestCase {
|
|||
types.add(randomAsciiOfLengthBetween(0, 50));
|
||||
}
|
||||
|
||||
RatedRequest original = createTestItem(indices, types);
|
||||
RatedRequest original = createTestItem(indices, types, randomBoolean());
|
||||
|
||||
List<NamedWriteableRegistry.Entry> namedWriteables = new ArrayList<>();
|
||||
namedWriteables.add(new NamedWriteableRegistry.Entry(QueryBuilder.class, MatchAllQueryBuilder.NAME, MatchAllQueryBuilder::new));
|
||||
|
@ -183,7 +183,7 @@ public class RatedRequestsTests extends ESTestCase {
|
|||
types.add(randomAsciiOfLengthBetween(0, 50));
|
||||
}
|
||||
|
||||
RatedRequest testItem = createTestItem(indices, types);
|
||||
RatedRequest testItem = createTestItem(indices, types, randomBoolean());
|
||||
|
||||
List<NamedWriteableRegistry.Entry> namedWriteables = new ArrayList<>();
|
||||
namedWriteables.add(new NamedWriteableRegistry.Entry(QueryBuilder.class, MatchAllQueryBuilder.NAME, MatchAllQueryBuilder::new));
|
||||
|
@ -338,23 +338,21 @@ public class RatedRequestsTests extends ESTestCase {
|
|||
+ " {\"_type\": \"testtype\", \"_index\": \"test\", \"_id\": \"2\", \"rating\" : 0 }, "
|
||||
+ " {\"_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);
|
||||
RankEvalContext rankContext = new RankEvalContext(ParseFieldMatcher.STRICT, queryContext,
|
||||
searchRequestParsers, null);
|
||||
RatedRequest specification = RatedRequest.fromXContent(parser, rankContext);
|
||||
assertEquals("my_qa_query", specification.getId());
|
||||
assertNotNull(specification.getTestRequest());
|
||||
List<RatedDocument> ratedDocs = specification.getRatedDocs();
|
||||
assertEquals(3, ratedDocs.size());
|
||||
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());
|
||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, querySpecString)) {
|
||||
RatedRequest specification = RatedRequest.fromXContent(parser);
|
||||
assertEquals("my_qa_query", specification.getId());
|
||||
assertNotNull(specification.getTestRequest());
|
||||
List<RatedDocument> ratedDocs = specification.getRatedDocs();
|
||||
assertEquals(3, ratedDocs.size());
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,9 +19,12 @@
|
|||
|
||||
package org.elasticsearch.index.rankeval;
|
||||
|
||||
import org.elasticsearch.common.ParseFieldMatcher;
|
||||
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.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.rankeval.PrecisionTests.Rating;
|
||||
import org.elasticsearch.search.SearchHit;
|
||||
|
@ -124,13 +127,16 @@ public class ReciprocalRankTests extends ESTestCase {
|
|||
|
||||
public void testXContentRoundtrip() throws IOException {
|
||||
ReciprocalRank testItem = createTestItem();
|
||||
XContentParser itemParser = RankEvalTestHelper.roundtrip(testItem);
|
||||
itemParser.nextToken();
|
||||
itemParser.nextToken();
|
||||
ReciprocalRank parsedItem = ReciprocalRank.fromXContent(itemParser, () -> ParseFieldMatcher.STRICT);
|
||||
assertNotSame(testItem, parsedItem);
|
||||
assertEquals(testItem, parsedItem);
|
||||
assertEquals(testItem.hashCode(), parsedItem.hashCode());
|
||||
XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values()));
|
||||
XContentBuilder shuffled = shuffleXContent(testItem.toXContent(builder, ToXContent.EMPTY_PARAMS));
|
||||
try (XContentParser itemParser = createParser(shuffled)) {
|
||||
itemParser.nextToken();
|
||||
itemParser.nextToken();
|
||||
ReciprocalRank parsedItem = ReciprocalRank.fromXContent(itemParser);
|
||||
assertNotSame(testItem, parsedItem);
|
||||
assertEquals(testItem, parsedItem);
|
||||
assertEquals(testItem.hashCode(), parsedItem.hashCode());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
apply plugin: 'elasticsearch.standalone-rest-test'
|
||||
apply plugin: 'elasticsearch.rest-test'
|
||||
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
|||
|
||||
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
||||
import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -35,7 +34,7 @@ public class SmokeTestRankEvalWithMustacheYAMLTestSuiteIT extends ESClientYamlSu
|
|||
}
|
||||
|
||||
@ParametersFactory
|
||||
public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
|
||||
public static Iterable<Object[]> parameters() throws IOException {
|
||||
return ESClientYamlSuiteTestCase.createParameters();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue