浏览代码

Replace RescoreBaseBuilder with AbstractRescoreBuilder

The current RescoreBaseBuilder only serves as a container
for a pair of the optional `window_size` parameter and
the actual rescorer. Instead of a wrapper object, this makes
it an abstract class that conrete implementations like
QueryRescoreBuilder can extend.
Christoph Büscher 9 年之前
父节点
当前提交
1bc0f7a8d0

+ 6 - 7
core/src/main/java/org/elasticsearch/action/search/SearchRequestBuilder.java

@@ -32,7 +32,6 @@ import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
 import org.elasticsearch.search.builder.SearchSourceBuilder;
 import org.elasticsearch.search.fetch.innerhits.InnerHitsBuilder;
 import org.elasticsearch.search.highlight.HighlightBuilder;
-import org.elasticsearch.search.rescore.RescoreBaseBuilder;
 import org.elasticsearch.search.rescore.RescoreBuilder;
 import org.elasticsearch.search.sort.SortBuilder;
 import org.elasticsearch.search.sort.SortOrder;
@@ -397,7 +396,7 @@ public class SearchRequestBuilder extends ActionRequestBuilder<SearchRequest, Se
      * @param rescorer rescorer configuration
      * @return this for chaining
      */
-    public SearchRequestBuilder setRescorer(RescoreBuilder rescorer) {
+    public SearchRequestBuilder setRescorer(RescoreBuilder<?> rescorer) {
         sourceBuilder().clearRescorers();
         return addRescorer(rescorer);
     }
@@ -412,7 +411,7 @@ public class SearchRequestBuilder extends ActionRequestBuilder<SearchRequest, Se
      */
     public SearchRequestBuilder setRescorer(RescoreBuilder rescorer, int window) {
         sourceBuilder().clearRescorers();
-        return addRescorer(rescorer, window);
+        return addRescorer(rescorer.windowSize(window));
     }
 
     /**
@@ -421,8 +420,8 @@ public class SearchRequestBuilder extends ActionRequestBuilder<SearchRequest, Se
      * @param rescorer rescorer configuration
      * @return this for chaining
      */
-    public SearchRequestBuilder addRescorer(RescoreBuilder rescorer) {
-        sourceBuilder().addRescorer(new RescoreBaseBuilder(rescorer));
+    public SearchRequestBuilder addRescorer(RescoreBuilder<?> rescorer) {
+        sourceBuilder().addRescorer(rescorer);
         return this;
     }
 
@@ -433,8 +432,8 @@ public class SearchRequestBuilder extends ActionRequestBuilder<SearchRequest, Se
      * @param window   rescore window
      * @return this for chaining
      */
-    public SearchRequestBuilder addRescorer(RescoreBuilder rescorer, int window) {
-        sourceBuilder().addRescorer(new RescoreBaseBuilder(rescorer).windowSize(window));
+    public SearchRequestBuilder addRescorer(RescoreBuilder<?> rescorer, int window) {
+        sourceBuilder().addRescorer(rescorer.windowSize(window));
         return this;
     }
 

+ 1 - 1
core/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java

@@ -679,7 +679,7 @@ public abstract class StreamInput extends InputStream {
     /**
      * Reads a {@link RescoreBuilder} from the current stream
      */
-    public RescoreBuilder readRescorer() throws IOException {
+    public RescoreBuilder<?> readRescorer() throws IOException {
         return readNamedWriteable(RescoreBuilder.class);
     }
 

+ 1 - 1
core/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java

@@ -681,7 +681,7 @@ public abstract class StreamOutput extends OutputStream {
      /**
      * Writes a {@link RescoreBuilder} to the current stream
      */
-    public void writeRescorer(RescoreBuilder rescorer) throws IOException {
+    public void writeRescorer(RescoreBuilder<?> rescorer) throws IOException {
         writeNamedWriteable(rescorer);
     }
 }

+ 2 - 3
core/src/main/java/org/elasticsearch/search/SearchService.java

@@ -61,7 +61,6 @@ import org.elasticsearch.index.mapper.FieldMapper;
 import org.elasticsearch.index.mapper.MappedFieldType;
 import org.elasticsearch.index.mapper.MappedFieldType.Loading;
 import org.elasticsearch.index.mapper.MapperService;
-import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
 import org.elasticsearch.index.query.QueryParseContext;
 import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.index.search.stats.ShardSearchStats;
@@ -101,7 +100,7 @@ import org.elasticsearch.search.query.QuerySearchRequest;
 import org.elasticsearch.search.query.QuerySearchResult;
 import org.elasticsearch.search.query.QuerySearchResultProvider;
 import org.elasticsearch.search.query.ScrollQuerySearchResult;
-import org.elasticsearch.search.rescore.RescoreBaseBuilder;
+import org.elasticsearch.search.rescore.RescoreBuilder;
 import org.elasticsearch.threadpool.ThreadPool;
 
 import java.io.IOException;
@@ -775,7 +774,7 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> imp
         }
         if (source.rescores() != null) {
             try {
-                for (RescoreBaseBuilder rescore : source.rescores()) {
+                for (RescoreBuilder<?> rescore : source.rescores()) {
                     context.addRescore(rescore.build(context.indexShard().getQueryShardContext()));
                 }
             } catch (IOException e) {

+ 12 - 11
core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java

@@ -46,7 +46,8 @@ import org.elasticsearch.search.fetch.innerhits.InnerHitsBuilder;
 import org.elasticsearch.search.fetch.source.FetchSourceContext;
 import org.elasticsearch.search.highlight.HighlightBuilder;
 import org.elasticsearch.search.internal.SearchContext;
-import org.elasticsearch.search.rescore.RescoreBaseBuilder;
+import org.elasticsearch.search.rescore.AbstractRescoreBuilder;
+import org.elasticsearch.search.rescore.RescoreBuilder;
 import org.elasticsearch.search.sort.SortBuilder;
 import org.elasticsearch.search.sort.SortBuilders;
 import org.elasticsearch.search.sort.SortOrder;
@@ -152,7 +153,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
 
     private BytesReference innerHitsBuilder;
 
-    private List<RescoreBaseBuilder> rescoreBuilders;
+    private List<RescoreBuilder<?>> rescoreBuilders;
 
     private ObjectFloatHashMap<String> indexBoost = null;
 
@@ -459,7 +460,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
         return suggestBuilder;
     }
 
-    public SearchSourceBuilder addRescorer(RescoreBaseBuilder rescoreBuilder) {
+    public SearchSourceBuilder addRescorer(RescoreBuilder<?> rescoreBuilder) {
             if (rescoreBuilders == null) {
                 rescoreBuilders = new ArrayList<>();
             }
@@ -491,7 +492,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
     /**
      * Gets the bytes representing the rescore builders for this request.
      */
-    public List<RescoreBaseBuilder> rescores() {
+    public List<RescoreBuilder<?>> rescores() {
         return rescoreBuilders;
     }
 
@@ -871,9 +872,9 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
                     }
                     builder.sorts = sorts;
                 } else if (context.parseFieldMatcher().match(currentFieldName, RESCORE_FIELD)) {
-                    List<RescoreBaseBuilder> rescoreBuilders = new ArrayList<>();
+                    List<RescoreBuilder<?>> rescoreBuilders = new ArrayList<>();
                     while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
-                        rescoreBuilders.add(RescoreBaseBuilder.PROTOTYPE.fromXContent(context));
+                        rescoreBuilders.add(AbstractRescoreBuilder.parseFromXContent(context));
                     }
                     builder.rescoreBuilders = rescoreBuilders;
                 } else if (context.parseFieldMatcher().match(currentFieldName, STATS_FIELD)) {
@@ -1040,7 +1041,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
 
         if (rescoreBuilders != null) {
             builder.startArray(RESCORE_FIELD.getPreferredName());
-            for (RescoreBaseBuilder rescoreBuilder : rescoreBuilders) {
+            for (RescoreBuilder<?> rescoreBuilder : rescoreBuilders) {
                 rescoreBuilder.toXContent(builder, params);
             }
             builder.endArray();
@@ -1187,9 +1188,9 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
         }
         if (in.readBoolean()) {
             int size = in.readVInt();
-            List<RescoreBaseBuilder> rescoreBuilders = new ArrayList<>();
+            List<RescoreBuilder<?>> rescoreBuilders = new ArrayList<>();
             for (int i = 0; i < size; i++) {
-                rescoreBuilders.add(RescoreBaseBuilder.PROTOTYPE.readFrom(in));
+                rescoreBuilders.add(in.readRescorer());
             }
             builder.rescoreBuilders = rescoreBuilders;
         }
@@ -1303,8 +1304,8 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
         out.writeBoolean(hasRescoreBuilders);
         if (hasRescoreBuilders) {
             out.writeVInt(rescoreBuilders.size());
-            for (RescoreBaseBuilder rescoreBuilder : rescoreBuilders) {
-                rescoreBuilder.writeTo(out);
+            for (RescoreBuilder<?> rescoreBuilder : rescoreBuilders) {
+                out.writeRescorer(rescoreBuilder);
             }
         }
         boolean hasScriptFields = scriptFields != null;

+ 28 - 48
core/src/main/java/org/elasticsearch/search/rescore/RescoreBaseBuilder.java → core/src/main/java/org/elasticsearch/search/rescore/AbstractRescoreBuilder.java

@@ -24,55 +24,40 @@ import org.elasticsearch.common.ParseField;
 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;
-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.index.query.MatchAllQueryBuilder;
 import org.elasticsearch.index.query.QueryBuilder;
 import org.elasticsearch.index.query.QueryParseContext;
-import org.elasticsearch.index.query.QueryShardContext;
 
 import java.io.IOException;
 import java.util.Objects;
 
 /**
- * The base builder for rescorers. Wraps a conrete instance of {@link RescoreBuilder} and
- * adds the ability to specify the optional `window_size` parameter
+ * The abstract base builder for instances of {@link RescoreBuilder}.
  */
-public class RescoreBaseBuilder implements ToXContent, Writeable<RescoreBaseBuilder> {
+public abstract class AbstractRescoreBuilder<RB extends AbstractRescoreBuilder<RB>> implements RescoreBuilder<RB> {
 
-    private RescoreBuilder rescorer;
-    private Integer windowSize;
-    public static final RescoreBaseBuilder PROTOTYPE = new RescoreBaseBuilder(new QueryRescorerBuilder(new MatchAllQueryBuilder()));
+    protected Integer windowSize;
 
     private static ParseField WINDOW_SIZE_FIELD = new ParseField("window_size");
 
-    public RescoreBaseBuilder(RescoreBuilder rescorer) {
-        if (rescorer == null) {
-            throw new IllegalArgumentException("rescorer cannot be null");
-        }
-        this.rescorer = rescorer;
-    }
-
-    public RescoreBuilder rescorer() {
-        return this.rescorer;
-    }
-
-    public RescoreBaseBuilder windowSize(int windowSize) {
+    @SuppressWarnings("unchecked")
+    @Override
+    public RB windowSize(int windowSize) {
         this.windowSize = windowSize;
-        return this;
+        return (RB) this;
     }
 
+    @Override
     public Integer windowSize() {
         return windowSize;
     }
 
-    public RescoreBaseBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+    public static RescoreBuilder<?> parseFromXContent(QueryParseContext parseContext) throws IOException {
         XContentParser parser = parseContext.parser();
         String fieldName = null;
-        RescoreBuilder rescorer = null;
+        AbstractRescoreBuilder<?> rescorer = null;
         Integer windowSize = null;
         XContentParser.Token token;
         while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
@@ -98,19 +83,10 @@ public class RescoreBaseBuilder implements ToXContent, Writeable<RescoreBaseBuil
         if (rescorer == null) {
             throw new ParsingException(parser.getTokenLocation(), "missing rescore type");
         }
-        RescoreBaseBuilder rescoreBuilder = new RescoreBaseBuilder(rescorer);
         if (windowSize != null) {
-            rescoreBuilder.windowSize(windowSize.intValue());
+            rescorer.windowSize(windowSize.intValue());
         }
-        return rescoreBuilder;
-    }
-
-    public RescoreSearchContext build(QueryShardContext context) throws IOException {
-        RescoreSearchContext rescoreContext = this.rescorer.build(context);
-        if (windowSize != null) {
-            rescoreContext.setWindowSize(this.windowSize);
-        }
-        return rescoreContext;
+        return rescorer;
     }
 
     @Override
@@ -119,54 +95,58 @@ public class RescoreBaseBuilder implements ToXContent, Writeable<RescoreBaseBuil
         if (windowSize != null) {
             builder.field("window_size", windowSize);
         }
-        rescorer.toXContent(builder, params);
+        doXContent(builder, params);
         builder.endObject();
         return builder;
     }
 
+    protected abstract void doXContent(XContentBuilder builder, Params params) throws IOException;
+
     public static QueryRescorerBuilder queryRescorer(QueryBuilder<?> queryBuilder) {
         return new QueryRescorerBuilder(queryBuilder);
     }
 
     @Override
-    public final int hashCode() {
-        return Objects.hash(windowSize, rescorer);
+    public int hashCode() {
+        return Objects.hash(windowSize);
     }
 
     @Override
-    public final boolean equals(Object obj) {
+    public boolean equals(Object obj) {
         if (this == obj) {
             return true;
         }
         if (obj == null || getClass() != obj.getClass()) {
             return false;
         }
-        RescoreBaseBuilder other = (RescoreBaseBuilder) obj;
-        return Objects.equals(windowSize, other.windowSize) &&
-               Objects.equals(rescorer, other.rescorer);
+        @SuppressWarnings("rawtypes")
+        AbstractRescoreBuilder other = (AbstractRescoreBuilder) obj;
+        return Objects.equals(windowSize, other.windowSize);
     }
 
     @Override
-    public RescoreBaseBuilder readFrom(StreamInput in) throws IOException {
-        RescoreBaseBuilder builder = new RescoreBaseBuilder(in.readRescorer());
+    public RB readFrom(StreamInput in) throws IOException {
+        RB builder = doReadFrom(in);
         builder.windowSize = in.readOptionalVInt();
         return builder;
     }
 
+    protected abstract RB doReadFrom(StreamInput in) throws IOException;
+
     @Override
     public void writeTo(StreamOutput out) throws IOException {
-        out.writeRescorer(rescorer);
+        doWriteTo(out);
         out.writeOptionalVInt(this.windowSize);
     }
 
+    protected abstract void doWriteTo(StreamOutput out) throws IOException;
+
     @Override
     public final String toString() {
         try {
             XContentBuilder builder = XContentFactory.jsonBuilder();
             builder.prettyPrint();
-            builder.startObject();
             toXContent(builder, EMPTY_PARAMS);
-            builder.endObject();
             return builder.string();
         } catch (Exception e) {
             return "{ \"error\" : \"" + ExceptionsHelper.detailedMessage(e) + "\"}";

+ 11 - 7
core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java

@@ -35,7 +35,7 @@ import java.io.IOException;
 import java.util.Locale;
 import java.util.Objects;
 
-public class QueryRescorerBuilder implements RescoreBuilder<QueryRescorerBuilder> {
+public class QueryRescorerBuilder extends AbstractRescoreBuilder<QueryRescorerBuilder> {
 
     public static final String NAME = "query";
 
@@ -131,14 +131,13 @@ public class QueryRescorerBuilder implements RescoreBuilder<QueryRescorerBuilder
     }
 
     @Override
-    public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+    public void doXContent(XContentBuilder builder, Params params) throws IOException {
         builder.startObject(NAME);
         builder.field(RESCORE_QUERY_FIELD.getPreferredName(), queryBuilder);
         builder.field(QUERY_WEIGHT_FIELD.getPreferredName(), queryWeight);
         builder.field(RESCORE_QUERY_WEIGHT_FIELD.getPreferredName(), rescoreQueryWeight);
         builder.field(SCORE_MODE_FIELD.getPreferredName(), scoreMode.name().toLowerCase(Locale.ROOT));
         builder.endObject();
-        return builder;
     }
 
     @Override
@@ -155,12 +154,16 @@ public class QueryRescorerBuilder implements RescoreBuilder<QueryRescorerBuilder
         queryRescoreContext.setQueryWeight(this.queryWeight);
         queryRescoreContext.setRescoreQueryWeight(this.rescoreQueryWeight);
         queryRescoreContext.setScoreMode(this.scoreMode);
+        if (this.windowSize != null) {
+            queryRescoreContext.setWindowSize(this.windowSize);
+        }
         return queryRescoreContext;
     }
 
     @Override
     public final int hashCode() {
-        return Objects.hash(getClass(), scoreMode, queryWeight, rescoreQueryWeight, queryBuilder);
+        int result = super.hashCode();
+        return 31 * result + Objects.hash(scoreMode, queryWeight, rescoreQueryWeight, queryBuilder);
     }
 
     @Override
@@ -172,14 +175,15 @@ public class QueryRescorerBuilder implements RescoreBuilder<QueryRescorerBuilder
             return false;
         }
         QueryRescorerBuilder other = (QueryRescorerBuilder) obj;
-        return Objects.equals(scoreMode, other.scoreMode) &&
+        return super.equals(obj) &&
+               Objects.equals(scoreMode, other.scoreMode) &&
                Objects.equals(queryWeight, other.queryWeight) &&
                Objects.equals(rescoreQueryWeight, other.rescoreQueryWeight) &&
                Objects.equals(queryBuilder, other.queryBuilder);
     }
 
     @Override
-    public QueryRescorerBuilder readFrom(StreamInput in) throws IOException {
+    public QueryRescorerBuilder doReadFrom(StreamInput in) throws IOException {
         QueryRescorerBuilder rescorer = new QueryRescorerBuilder(in.readQuery());
         rescorer.setScoreMode(QueryRescoreMode.PROTOTYPE.readFrom(in));
         rescorer.setRescoreQueryWeight(in.readFloat());
@@ -188,7 +192,7 @@ public class QueryRescorerBuilder implements RescoreBuilder<QueryRescorerBuilder
     }
 
     @Override
-    public void writeTo(StreamOutput out) throws IOException {
+    public void doWriteTo(StreamOutput out) throws IOException {
         out.writeQuery(queryBuilder);
         scoreMode.writeTo(out);
         out.writeFloat(rescoreQueryWeight);

+ 5 - 1
core/src/main/java/org/elasticsearch/search/rescore/RescoreBuilder.java

@@ -26,9 +26,13 @@ import org.elasticsearch.index.query.QueryShardContext;
 
 import java.io.IOException;
 
-public interface RescoreBuilder<RB extends RescoreBuilder> extends ToXContent, NamedWriteable<RB> {
+public interface RescoreBuilder<RB extends RescoreBuilder<?>> extends ToXContent, NamedWriteable<RB> {
 
     RescoreSearchContext build(QueryShardContext context) throws IOException;
 
     RB fromXContent(QueryParseContext parseContext) throws IOException;
+
+    RB windowSize(int windowSize);
+
+    Integer windowSize();
 }

+ 24 - 24
core/src/test/java/org/elasticsearch/search/functionscore/QueryRescorerIT.java

@@ -37,9 +37,9 @@ import org.elasticsearch.index.query.QueryBuilders;
 import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
 import org.elasticsearch.search.SearchHit;
 import org.elasticsearch.search.SearchHits;
+import org.elasticsearch.search.rescore.AbstractRescoreBuilder;
 import org.elasticsearch.search.rescore.QueryRescoreMode;
 import org.elasticsearch.search.rescore.QueryRescorerBuilder;
-import org.elasticsearch.search.rescore.RescoreBaseBuilder;
 import org.elasticsearch.test.ESIntegTestCase;
 
 import java.util.Arrays;
@@ -80,7 +80,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
         for (int j = 0 ; j < iters; j++) {
             SearchResponse searchResponse = client().prepareSearch()
                     .setQuery(QueryBuilders.matchAllQuery())
-                    .setRescorer(RescoreBaseBuilder.queryRescorer(
+                    .setRescorer(AbstractRescoreBuilder.queryRescorer(
                             QueryBuilders.functionScoreQuery(QueryBuilders.matchAllQuery(),
                                                     ScoreFunctionBuilders.weightFactorFunction(100)).boostMode(CombineFunction.REPLACE))
                                     .setQueryWeight(0.0f).setRescoreQueryWeight(1.0f), 1).setSize(randomIntBetween(2, 10)).execute()
@@ -116,7 +116,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
         SearchResponse searchResponse = client().prepareSearch()
                 .setQuery(QueryBuilders.matchQuery("field1", "the quick brown").operator(Operator.OR))
                 .setRescorer(
-                        RescoreBaseBuilder.queryRescorer(QueryBuilders.matchPhraseQuery("field1", "quick brown").slop(2).boost(4.0f))
+                        AbstractRescoreBuilder.queryRescorer(QueryBuilders.matchPhraseQuery("field1", "quick brown").slop(2).boost(4.0f))
                                 .setRescoreQueryWeight(2), 5).execute().actionGet();
 
         assertThat(searchResponse.getHits().totalHits(), equalTo(3l));
@@ -126,7 +126,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
 
         searchResponse = client().prepareSearch()
                 .setQuery(QueryBuilders.matchQuery("field1", "the quick brown").operator(Operator.OR))
-                .setRescorer(RescoreBaseBuilder.queryRescorer(QueryBuilders.matchPhraseQuery("field1", "the quick brown").slop(3)), 5)
+                .setRescorer(AbstractRescoreBuilder.queryRescorer(QueryBuilders.matchPhraseQuery("field1", "the quick brown").slop(3)), 5)
                 .execute().actionGet();
 
         assertHitCount(searchResponse, 3);
@@ -136,7 +136,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
 
         searchResponse = client().prepareSearch()
                 .setQuery(QueryBuilders.matchQuery("field1", "the quick brown").operator(Operator.OR))
-                .setRescorer(RescoreBaseBuilder.queryRescorer((QueryBuilders.matchPhraseQuery("field1", "the quick brown"))), 5).execute()
+                .setRescorer(AbstractRescoreBuilder.queryRescorer((QueryBuilders.matchPhraseQuery("field1", "the quick brown"))), 5).execute()
                 .actionGet();
 
         assertHitCount(searchResponse, 3);
@@ -181,7 +181,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
                 .setFrom(0)
                 .setSize(5)
                 .setRescorer(
-                        RescoreBaseBuilder.queryRescorer(QueryBuilders.matchPhraseQuery("field1", "lexington avenue massachusetts").slop(3))
+                        AbstractRescoreBuilder.queryRescorer(QueryBuilders.matchPhraseQuery("field1", "lexington avenue massachusetts").slop(3))
                                 .setQueryWeight(0.6f).setRescoreQueryWeight(2.0f), 20).execute().actionGet();
 
         assertThat(searchResponse.getHits().hits().length, equalTo(5));
@@ -197,7 +197,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
                 .setSize(5)
                 .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                 .setRescorer(
-                        RescoreBaseBuilder.queryRescorer(QueryBuilders.matchPhraseQuery("field1", "lexington avenue massachusetts").slop(3))
+                        AbstractRescoreBuilder.queryRescorer(QueryBuilders.matchPhraseQuery("field1", "lexington avenue massachusetts").slop(3))
                                 .setQueryWeight(0.6f).setRescoreQueryWeight(2.0f), 20).execute().actionGet();
 
         assertThat(searchResponse.getHits().hits().length, equalTo(5));
@@ -214,7 +214,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
                 .setSize(5)
                 .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                 .setRescorer(
-                        RescoreBaseBuilder.queryRescorer(QueryBuilders.matchPhraseQuery("field1", "lexington avenue massachusetts").slop(3))
+                        AbstractRescoreBuilder.queryRescorer(QueryBuilders.matchPhraseQuery("field1", "lexington avenue massachusetts").slop(3))
                                 .setQueryWeight(0.6f).setRescoreQueryWeight(2.0f), 20).execute().actionGet();
 
         assertThat(searchResponse.getHits().hits().length, equalTo(5));
@@ -263,7 +263,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
                 .setFrom(0)
                 .setSize(5)
                 .setRescorer(
-                        RescoreBaseBuilder.queryRescorer(QueryBuilders.matchPhraseQuery("field1", "lexington avenue massachusetts").slop(3))
+                        AbstractRescoreBuilder.queryRescorer(QueryBuilders.matchPhraseQuery("field1", "lexington avenue massachusetts").slop(3))
                                 .setQueryWeight(0.6f).setRescoreQueryWeight(2.0f), 2).execute().actionGet();
         // Only top 2 hits were re-ordered:
         assertThat(searchResponse.getHits().hits().length, equalTo(4));
@@ -280,7 +280,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
                 .setFrom(0)
                 .setSize(5)
                 .setRescorer(
-                        RescoreBaseBuilder.queryRescorer(QueryBuilders.matchPhraseQuery("field1", "lexington avenue massachusetts").slop(3))
+                        AbstractRescoreBuilder.queryRescorer(QueryBuilders.matchPhraseQuery("field1", "lexington avenue massachusetts").slop(3))
                                 .setQueryWeight(0.6f).setRescoreQueryWeight(2.0f), 3).execute().actionGet();
 
         // Only top 3 hits were re-ordered:
@@ -333,7 +333,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
                 .setFrom(0)
                 .setSize(5)
                 .setRescorer(
-                        RescoreBaseBuilder.queryRescorer(QueryBuilders.matchPhraseQuery("field1", "lexington avenue massachusetts").slop(3))
+                        AbstractRescoreBuilder.queryRescorer(QueryBuilders.matchPhraseQuery("field1", "lexington avenue massachusetts").slop(3))
                                 .setQueryWeight(1.0f).setRescoreQueryWeight(-1f), 3).execute().actionGet();
 
         // 6 and 1 got worse, and then the hit (2) outside the rescore window were sorted ahead:
@@ -424,7 +424,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
                     .setFrom(0)
                     .setSize(resultSize)
                     .setRescorer(
-                            RescoreBaseBuilder
+                            AbstractRescoreBuilder
                                     .queryRescorer(
                                             QueryBuilders
                                                     .constantScoreQuery(QueryBuilders.matchPhraseQuery("field1", intToEnglish).slop(3)))
@@ -462,7 +462,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
                     .setFrom(0)
                     .setSize(resultSize)
                     .setRescorer(
-                            RescoreBaseBuilder
+                            AbstractRescoreBuilder
                                     .queryRescorer(
                                             QueryBuilders
                                                     .constantScoreQuery(QueryBuilders.matchPhraseQuery("field1", "not in the index").slop(3)))
@@ -480,7 +480,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
                     .setFrom(0)
                     .setSize(resultSize)
                     .setRescorer(
-                            RescoreBaseBuilder
+                            AbstractRescoreBuilder
                                     .queryRescorer(
                                             QueryBuilders.matchPhraseQuery("field1", intToEnglish).slop(0))
                                     .setQueryWeight(1.0f).setRescoreQueryWeight(1.0f), 2 * rescoreWindow).execute().actionGet();
@@ -512,7 +512,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
                     .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                     .setQuery(QueryBuilders.matchQuery("field1", "the quick brown").operator(Operator.OR))
                     .setRescorer(
-                            RescoreBaseBuilder.queryRescorer(QueryBuilders.matchPhraseQuery("field1", "the quick brown").slop(2).boost(4.0f))
+                            AbstractRescoreBuilder.queryRescorer(QueryBuilders.matchPhraseQuery("field1", "the quick brown").slop(2).boost(4.0f))
                                     .setQueryWeight(0.5f).setRescoreQueryWeight(0.4f), 5).setExplain(true).execute()
                     .actionGet();
             assertHitCount(searchResponse, 3);
@@ -538,7 +538,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
         String[] scoreModes = new String[]{ "max", "min", "avg", "total", "multiply", "" };
         String[] descriptionModes = new String[]{ "max of:", "min of:", "avg of:", "sum of:", "product of:", "sum of:" };
         for (int innerMode = 0; innerMode < scoreModes.length; innerMode++) {
-            QueryRescorerBuilder innerRescoreQuery = RescoreBaseBuilder.queryRescorer(QueryBuilders.matchQuery("field1", "the quick brown").boost(4.0f))
+            QueryRescorerBuilder innerRescoreQuery = AbstractRescoreBuilder.queryRescorer(QueryBuilders.matchQuery("field1", "the quick brown").boost(4.0f))
                 .setQueryWeight(0.5f).setRescoreQueryWeight(0.4f);
 
             if (!"".equals(scoreModes[innerMode])) {
@@ -561,7 +561,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
             }
 
             for (int outerMode = 0; outerMode < scoreModes.length; outerMode++) {
-                QueryRescorerBuilder outerRescoreQuery = RescoreBaseBuilder.queryRescorer(QueryBuilders.matchQuery("field1", "the quick brown")
+                QueryRescorerBuilder outerRescoreQuery = AbstractRescoreBuilder.queryRescorer(QueryBuilders.matchQuery("field1", "the quick brown")
                         .boost(4.0f)).setQueryWeight(0.5f).setRescoreQueryWeight(0.4f);
 
                 if (!"".equals(scoreModes[outerMode])) {
@@ -572,7 +572,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
                         .prepareSearch()
                         .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                         .setQuery(QueryBuilders.matchQuery("field1", "the quick brown").operator(Operator.OR))
-                        .addRescorer(innerRescoreQuery, 5).addRescorer(outerRescoreQuery, 10)
+                        .addRescorer(innerRescoreQuery, 5).addRescorer(outerRescoreQuery.windowSize(10))
                         .setExplain(true).get();
                 assertHitCount(searchResponse, 3);
                 assertFirstHit(searchResponse, hasId("1"));
@@ -599,7 +599,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
             for (int i = 0; i < numDocs - 4; i++) {
                 String[] intToEnglish = new String[] { English.intToEnglish(i), English.intToEnglish(i + 1), English.intToEnglish(i + 2), English.intToEnglish(i + 3) };
 
-                QueryRescorerBuilder rescoreQuery = RescoreBaseBuilder
+                QueryRescorerBuilder rescoreQuery = AbstractRescoreBuilder
                         .queryRescorer(
                                 QueryBuilders.boolQuery()
                                         .disableCoord(true)
@@ -682,10 +682,10 @@ public class QueryRescorerIT extends ESIntegTestCase {
 
     public void testMultipleRescores() throws Exception {
         int numDocs = indexRandomNumbers("keyword", 1, true);
-        QueryRescorerBuilder eightIsGreat = RescoreBaseBuilder.queryRescorer(
+        QueryRescorerBuilder eightIsGreat = AbstractRescoreBuilder.queryRescorer(
                 QueryBuilders.functionScoreQuery(QueryBuilders.termQuery("field1", English.intToEnglish(8)),
                         ScoreFunctionBuilders.weightFactorFunction(1000.0f)).boostMode(CombineFunction.REPLACE)).setScoreMode(QueryRescoreMode.Total);
-        QueryRescorerBuilder sevenIsBetter = RescoreBaseBuilder.queryRescorer(
+        QueryRescorerBuilder sevenIsBetter = AbstractRescoreBuilder.queryRescorer(
                 QueryBuilders.functionScoreQuery(QueryBuilders.termQuery("field1", English.intToEnglish(7)),
                         ScoreFunctionBuilders.weightFactorFunction(10000.0f)).boostMode(CombineFunction.REPLACE))
                 .setScoreMode(QueryRescoreMode.Total);
@@ -703,10 +703,10 @@ public class QueryRescorerIT extends ESIntegTestCase {
         // We have no idea what the second hit will be because we didn't get a chance to look for seven
 
         // Now use one rescore to drag the number we're looking for into the window of another
-        QueryRescorerBuilder ninetyIsGood = RescoreBaseBuilder.queryRescorer(
+        QueryRescorerBuilder ninetyIsGood = AbstractRescoreBuilder.queryRescorer(
                 QueryBuilders.functionScoreQuery(QueryBuilders.queryStringQuery("*ninety*"), ScoreFunctionBuilders.weightFactorFunction(1000.0f))
                         .boostMode(CombineFunction.REPLACE)).setScoreMode(QueryRescoreMode.Total);
-        QueryRescorerBuilder oneToo = RescoreBaseBuilder.queryRescorer(
+        QueryRescorerBuilder oneToo = AbstractRescoreBuilder.queryRescorer(
                 QueryBuilders.functionScoreQuery(QueryBuilders.queryStringQuery("*one*"), ScoreFunctionBuilders.weightFactorFunction(1000.0f))
                         .boostMode(CombineFunction.REPLACE)).setScoreMode(QueryRescoreMode.Total);
         request.clearRescorers().addRescorer(ninetyIsGood, numDocs).addRescorer(oneToo, 10);
@@ -759,7 +759,7 @@ public class QueryRescorerIT extends ESIntegTestCase {
         request.setQuery(QueryBuilders.termQuery("text", "hello"));
         request.setFrom(1);
         request.setSize(4);
-        request.addRescorer(RescoreBaseBuilder.queryRescorer(QueryBuilders.matchAllQuery()), 50);
+        request.addRescorer(AbstractRescoreBuilder.queryRescorer(QueryBuilders.matchAllQuery()), 50);
 
         assertEquals(4, request.get().getHits().hits().length);
     }

+ 25 - 26
core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java

@@ -86,8 +86,8 @@ public class QueryRescoreBuilderTests extends ESTestCase {
      */
     public void testSerialization() throws IOException {
         for (int runs = 0; runs < NUMBER_OF_TESTBUILDERS; runs++) {
-            RescoreBaseBuilder original = randomRescoreBuilder();
-            RescoreBaseBuilder deserialized = serializedCopy(original);
+            RescoreBuilder<?> original = randomRescoreBuilder();
+            RescoreBuilder<?> deserialized = serializedCopy(original);
             assertEquals(deserialized, original);
             assertEquals(deserialized.hashCode(), original.hashCode());
             assertNotSame(deserialized, original);
@@ -99,7 +99,7 @@ public class QueryRescoreBuilderTests extends ESTestCase {
      */
     public void testEqualsAndHashcode() throws IOException {
         for (int runs = 0; runs < NUMBER_OF_TESTBUILDERS; runs++) {
-            RescoreBaseBuilder firstBuilder = randomRescoreBuilder();
+            RescoreBuilder<?> firstBuilder = randomRescoreBuilder();
             assertFalse("rescore builder is equal to null", firstBuilder.equals(null));
             assertFalse("rescore builder is equal to incompatible type", firstBuilder.equals(""));
             assertTrue("rescore builder is not equal to self", firstBuilder.equals(firstBuilder));
@@ -107,13 +107,13 @@ public class QueryRescoreBuilderTests extends ESTestCase {
                     equalTo(firstBuilder.hashCode()));
             assertThat("different rescore builder should not be equal", mutate(firstBuilder), not(equalTo(firstBuilder)));
 
-            RescoreBaseBuilder secondBuilder = serializedCopy(firstBuilder);
+            RescoreBuilder<?> secondBuilder = serializedCopy(firstBuilder);
             assertTrue("rescore builder is not equal to self", secondBuilder.equals(secondBuilder));
             assertTrue("rescore builder is not equal to its copy", firstBuilder.equals(secondBuilder));
             assertTrue("equals is not symmetric", secondBuilder.equals(firstBuilder));
             assertThat("rescore builder copy's hashcode is different from original hashcode", secondBuilder.hashCode(), equalTo(firstBuilder.hashCode()));
 
-            RescoreBaseBuilder thirdBuilder = serializedCopy(secondBuilder);
+            RescoreBuilder<?> thirdBuilder = serializedCopy(secondBuilder);
             assertTrue("rescore builder is not equal to self", thirdBuilder.equals(thirdBuilder));
             assertTrue("rescore builder is not equal to its copy", secondBuilder.equals(thirdBuilder));
             assertThat("rescore builder copy's hashcode is different from original hashcode", secondBuilder.hashCode(), equalTo(thirdBuilder.hashCode()));
@@ -131,19 +131,19 @@ public class QueryRescoreBuilderTests extends ESTestCase {
         QueryParseContext context = new QueryParseContext(indicesQueriesRegistry);
         context.parseFieldMatcher(new ParseFieldMatcher(Settings.EMPTY));
         for (int runs = 0; runs < NUMBER_OF_TESTBUILDERS; runs++) {
-            RescoreBaseBuilder rescoreBuilder = randomRescoreBuilder();
+            RescoreBuilder<?> rescoreBuilder = randomRescoreBuilder();
 
             XContentParser parser = createParser(rescoreBuilder);
             context.reset(parser);
             parser.nextToken();
-            RescoreBaseBuilder secondRescoreBuilder = RescoreBaseBuilder.PROTOTYPE.fromXContent(context);
+            RescoreBuilder<?> secondRescoreBuilder = AbstractRescoreBuilder.parseFromXContent(context);
             assertNotSame(rescoreBuilder, secondRescoreBuilder);
             assertEquals(rescoreBuilder, secondRescoreBuilder);
             assertEquals(rescoreBuilder.hashCode(), secondRescoreBuilder.hashCode());
         }
     }
 
-    private static XContentParser createParser(RescoreBaseBuilder rescoreBuilder) throws IOException {
+    private static XContentParser createParser(RescoreBuilder<?> rescoreBuilder) throws IOException {
         XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values()));
         if (randomBoolean()) {
             builder.prettyPrint();
@@ -171,7 +171,7 @@ public class QueryRescoreBuilderTests extends ESTestCase {
         };
 
         for (int runs = 0; runs < NUMBER_OF_TESTBUILDERS; runs++) {
-            RescoreBaseBuilder rescoreBuilder = randomRescoreBuilder();
+            RescoreBuilder<?> rescoreBuilder = randomRescoreBuilder();
             QueryRescoreContext rescoreContext = (QueryRescoreContext) rescoreBuilder.build(mockShardContext);
             XContentParser parser = createParser(rescoreBuilder);
 
@@ -198,7 +198,7 @@ public class QueryRescoreBuilderTests extends ESTestCase {
                 "}\n";
         prepareContext(context, rescoreElement);
         try {
-            RescoreBaseBuilder.PROTOTYPE.fromXContent(context);
+            AbstractRescoreBuilder.parseFromXContent(context);
             fail("expected a parsing exception");
         } catch (ParsingException e) {
             assertEquals("rescore doesn't support rescorer with name [bad_rescorer_name]", e.getMessage());
@@ -209,7 +209,7 @@ public class QueryRescoreBuilderTests extends ESTestCase {
                 "}\n";
         prepareContext(context, rescoreElement);
         try {
-            RescoreBaseBuilder.PROTOTYPE.fromXContent(context);
+            AbstractRescoreBuilder.parseFromXContent(context);
             fail("expected a parsing exception");
         } catch (ParsingException e) {
             assertEquals("rescore doesn't support [bad_fieldName]", e.getMessage());
@@ -221,7 +221,7 @@ public class QueryRescoreBuilderTests extends ESTestCase {
                 "}\n";
         prepareContext(context, rescoreElement);
         try {
-            RescoreBaseBuilder.PROTOTYPE.fromXContent(context);
+            AbstractRescoreBuilder.parseFromXContent(context);
             fail("expected a parsing exception");
         } catch (ParsingException e) {
             assertEquals("unexpected token [START_ARRAY] after [query]", e.getMessage());
@@ -230,7 +230,7 @@ public class QueryRescoreBuilderTests extends ESTestCase {
         rescoreElement = "{ }";
         prepareContext(context, rescoreElement);
         try {
-            RescoreBaseBuilder.PROTOTYPE.fromXContent(context);
+            AbstractRescoreBuilder.parseFromXContent(context);
             fail("expected a parsing exception");
         } catch (ParsingException e) {
             assertEquals("missing rescore type", e.getMessage());
@@ -242,7 +242,7 @@ public class QueryRescoreBuilderTests extends ESTestCase {
                 "}\n";
         prepareContext(context, rescoreElement);
         try {
-            RescoreBaseBuilder.PROTOTYPE.fromXContent(context);
+            AbstractRescoreBuilder.parseFromXContent(context);
             fail("expected a parsing exception");
         } catch (IllegalArgumentException e) {
             assertEquals("[query] unknown field [bad_fieldname], parser not found", e.getMessage());
@@ -254,7 +254,7 @@ public class QueryRescoreBuilderTests extends ESTestCase {
                 "}\n";
         prepareContext(context, rescoreElement);
         try {
-            RescoreBaseBuilder.PROTOTYPE.fromXContent(context);
+            AbstractRescoreBuilder.parseFromXContent(context);
             fail("expected a parsing exception");
         } catch (ParsingException e) {
             assertEquals("[query] failed to parse field [rescore_query]", e.getMessage());
@@ -265,7 +265,7 @@ public class QueryRescoreBuilderTests extends ESTestCase {
                 "    \"query\" : { \"rescore_query\" : { \"match_all\" : { } } } \n"
                 + "}\n";
         prepareContext(context, rescoreElement);
-        RescoreBaseBuilder.PROTOTYPE.fromXContent(context);
+        AbstractRescoreBuilder.parseFromXContent(context);
     }
 
     /**
@@ -278,8 +278,8 @@ public class QueryRescoreBuilderTests extends ESTestCase {
         assertTrue(parser.nextToken() == XContentParser.Token.START_OBJECT);
     }
 
-    private static RescoreBaseBuilder mutate(RescoreBaseBuilder original) throws IOException {
-        RescoreBaseBuilder mutation = serializedCopy(original);
+    private static RescoreBuilder<?> mutate(RescoreBuilder<?> original) throws IOException {
+        RescoreBuilder<?> mutation = serializedCopy(original);
         if (randomBoolean()) {
             Integer windowSize = original.windowSize();
             if (windowSize != null) {
@@ -288,7 +288,7 @@ public class QueryRescoreBuilderTests extends ESTestCase {
                 mutation.windowSize(randomIntBetween(0, 100));
             }
         } else {
-            QueryRescorerBuilder queryRescorer = (QueryRescorerBuilder) mutation.rescorer();
+            QueryRescorerBuilder queryRescorer = (QueryRescorerBuilder) mutation;
             switch (randomIntBetween(0, 3)) {
             case 0:
                 queryRescorer.setQueryWeight(queryRescorer.getQueryWeight() + 0.1f);
@@ -317,7 +317,7 @@ public class QueryRescoreBuilderTests extends ESTestCase {
     /**
      * create random shape that is put under test
      */
-    public static RescoreBaseBuilder randomRescoreBuilder() {
+    public static org.elasticsearch.search.rescore.QueryRescorerBuilder randomRescoreBuilder() {
         QueryBuilder<MatchAllQueryBuilder> queryBuilder = new MatchAllQueryBuilder().boost(randomFloat()).queryName(randomAsciiOfLength(20));
         org.elasticsearch.search.rescore.QueryRescorerBuilder rescorer = new
                 org.elasticsearch.search.rescore.QueryRescorerBuilder(queryBuilder);
@@ -330,18 +330,17 @@ public class QueryRescoreBuilderTests extends ESTestCase {
         if (randomBoolean()) {
             rescorer.setScoreMode(randomFrom(QueryRescoreMode.values()));
         }
-        RescoreBaseBuilder builder = new RescoreBaseBuilder(rescorer);
         if (randomBoolean()) {
-            builder.windowSize(randomIntBetween(0, 100));
+            rescorer.windowSize(randomIntBetween(0, 100));
         }
-        return builder;
+        return rescorer;
     }
 
-    private static RescoreBaseBuilder serializedCopy(RescoreBaseBuilder original) throws IOException {
+    private static RescoreBuilder<?> serializedCopy(RescoreBuilder<?> original) throws IOException {
         try (BytesStreamOutput output = new BytesStreamOutput()) {
-            original.writeTo(output);
+            output.writeRescorer(original);
             try (StreamInput in = new NamedWriteableAwareStreamInput(StreamInput.wrap(output.bytes()), namedWriteableRegistry)) {
-                return RescoreBaseBuilder.PROTOTYPE.readFrom(in);
+                return in.readRescorer();
             }
         }
     }