diff options
Diffstat (limited to 'core/src/main/java/org/elasticsearch/search')
12 files changed, 211 insertions, 265 deletions
diff --git a/core/src/main/java/org/elasticsearch/search/SearchModule.java b/core/src/main/java/org/elasticsearch/search/SearchModule.java index 96db4b1146..8756a31c44 100644 --- a/core/src/main/java/org/elasticsearch/search/SearchModule.java +++ b/core/src/main/java/org/elasticsearch/search/SearchModule.java @@ -21,21 +21,13 @@ package org.elasticsearch.search; import org.apache.lucene.search.BooleanQuery; import org.elasticsearch.common.geo.ShapesAvailability; -import org.elasticsearch.common.geo.builders.CircleBuilder; -import org.elasticsearch.common.geo.builders.EnvelopeBuilder; -import org.elasticsearch.common.geo.builders.GeometryCollectionBuilder; -import org.elasticsearch.common.geo.builders.LineStringBuilder; -import org.elasticsearch.common.geo.builders.MultiLineStringBuilder; -import org.elasticsearch.common.geo.builders.MultiPointBuilder; -import org.elasticsearch.common.geo.builders.MultiPolygonBuilder; -import org.elasticsearch.common.geo.builders.PointBuilder; -import org.elasticsearch.common.geo.builders.PolygonBuilder; -import org.elasticsearch.common.geo.builders.ShapeBuilder; +import org.elasticsearch.common.geo.builders.ShapeBuilders; import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.inject.multibindings.Multibinder; import org.elasticsearch.common.io.stream.NamedWriteable; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.index.percolator.PercolatorHighlightSubFetchPhase; import org.elasticsearch.index.query.BoolQueryParser; import org.elasticsearch.index.query.BoostingQueryParser; import org.elasticsearch.index.query.CommonTermsQueryParser; @@ -216,7 +208,6 @@ import org.elasticsearch.search.fetch.fielddata.FieldDataFieldsFetchSubPhase; import org.elasticsearch.search.fetch.innerhits.InnerHitsFetchSubPhase; import org.elasticsearch.search.fetch.matchedqueries.MatchedQueriesFetchSubPhase; import org.elasticsearch.search.fetch.parent.ParentFieldSubFetchPhase; -import org.elasticsearch.index.percolator.PercolatorHighlightSubFetchPhase; import org.elasticsearch.search.fetch.script.ScriptFieldsFetchSubPhase; import org.elasticsearch.search.fetch.source.FetchSourceSubPhase; import org.elasticsearch.search.fetch.version.VersionFetchSubPhase; @@ -286,6 +277,8 @@ public class SearchModule extends AbstractModule { registerBuiltinFunctionScoreParsers(); registerBuiltinQueryParsers(); + registerBuiltinRescorers(); + registerBuiltinSorts(); } public void registerHighlighter(String key, Class<? extends Highlighter> clazz) { @@ -350,8 +343,6 @@ public class SearchModule extends AbstractModule { configureSuggesters(); configureFetchSubPhase(); configureShapes(); - configureRescorers(); - configureSorts(); } protected void configureFetchSubPhase() { @@ -479,27 +470,19 @@ public class SearchModule extends AbstractModule { private void configureShapes() { if (ShapesAvailability.JTS_AVAILABLE && ShapesAvailability.SPATIAL4J_AVAILABLE) { - namedWriteableRegistry.registerPrototype(ShapeBuilder.class, PointBuilder.PROTOTYPE); - namedWriteableRegistry.registerPrototype(ShapeBuilder.class, CircleBuilder.PROTOTYPE); - namedWriteableRegistry.registerPrototype(ShapeBuilder.class, EnvelopeBuilder.PROTOTYPE); - namedWriteableRegistry.registerPrototype(ShapeBuilder.class, MultiPointBuilder.PROTOTYPE); - namedWriteableRegistry.registerPrototype(ShapeBuilder.class, LineStringBuilder.PROTOTYPE); - namedWriteableRegistry.registerPrototype(ShapeBuilder.class, MultiLineStringBuilder.PROTOTYPE); - namedWriteableRegistry.registerPrototype(ShapeBuilder.class, PolygonBuilder.PROTOTYPE); - namedWriteableRegistry.registerPrototype(ShapeBuilder.class, MultiPolygonBuilder.PROTOTYPE); - namedWriteableRegistry.registerPrototype(ShapeBuilder.class, GeometryCollectionBuilder.PROTOTYPE); + ShapeBuilders.register(namedWriteableRegistry); } } - private void configureRescorers() { - namedWriteableRegistry.registerPrototype(RescoreBuilder.class, QueryRescorerBuilder.PROTOTYPE); + private void registerBuiltinRescorers() { + namedWriteableRegistry.register(RescoreBuilder.class, QueryRescorerBuilder.NAME, QueryRescorerBuilder::new); } - private void configureSorts() { - namedWriteableRegistry.registerPrototype(SortBuilder.class, GeoDistanceSortBuilder.PROTOTYPE); - namedWriteableRegistry.registerPrototype(SortBuilder.class, ScoreSortBuilder.PROTOTYPE); - namedWriteableRegistry.registerPrototype(SortBuilder.class, ScriptSortBuilder.PROTOTYPE); - namedWriteableRegistry.registerPrototype(SortBuilder.class, FieldSortBuilder.PROTOTYPE); + private void registerBuiltinSorts() { + namedWriteableRegistry.register(SortBuilder.class, GeoDistanceSortBuilder.NAME, GeoDistanceSortBuilder::new); + namedWriteableRegistry.register(SortBuilder.class, ScoreSortBuilder.NAME, ScoreSortBuilder::new); + namedWriteableRegistry.register(SortBuilder.class, ScriptSortBuilder.NAME, ScriptSortBuilder::new); + namedWriteableRegistry.register(SortBuilder.class, FieldSortBuilder.NAME, FieldSortBuilder::new); } private void registerBuiltinFunctionScoreParsers() { diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/range/geodistance/GeoDistanceAggregatorBuilder.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/range/geodistance/GeoDistanceAggregatorBuilder.java index 5969265f75..a11bfd113b 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/range/geodistance/GeoDistanceAggregatorBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/range/geodistance/GeoDistanceAggregatorBuilder.java @@ -211,7 +211,7 @@ public class GeoDistanceAggregatorBuilder extends ValuesSourceAggregatorBuilder< } factory.keyed = in.readBoolean(); factory.distanceType = GeoDistance.readGeoDistanceFrom(in); - factory.unit = DistanceUnit.readDistanceUnit(in); + factory.unit = DistanceUnit.readFromStream(in); return factory; } @@ -225,7 +225,7 @@ public class GeoDistanceAggregatorBuilder extends ValuesSourceAggregatorBuilder< } out.writeBoolean(keyed); distanceType.writeTo(out); - DistanceUnit.writeDistanceUnit(out, unit); + unit.writeTo(out); } @Override diff --git a/core/src/main/java/org/elasticsearch/search/rescore/QueryRescoreMode.java b/core/src/main/java/org/elasticsearch/search/rescore/QueryRescoreMode.java index b0d5a325e5..959bd51270 100644 --- a/core/src/main/java/org/elasticsearch/search/rescore/QueryRescoreMode.java +++ b/core/src/main/java/org/elasticsearch/search/rescore/QueryRescoreMode.java @@ -85,10 +85,7 @@ public enum QueryRescoreMode implements Writeable<QueryRescoreMode> { public abstract float combine(float primary, float secondary); - static QueryRescoreMode PROTOTYPE = Total; - - @Override - public QueryRescoreMode readFrom(StreamInput in) throws IOException { + public static QueryRescoreMode readFromStream(StreamInput in) throws IOException { int ordinal = in.readVInt(); if (ordinal < 0 || ordinal >= values().length) { throw new IOException("Unknown ScoreMode ordinal [" + ordinal + "]"); diff --git a/core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java b/core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java index c65fca79a9..8556426557 100644 --- a/core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java @@ -25,7 +25,6 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.ObjectParser; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.index.query.MatchAllQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryShardContext; @@ -39,8 +38,6 @@ public class QueryRescorerBuilder extends RescoreBuilder<QueryRescorerBuilder> { public static final String NAME = "query"; - public static final QueryRescorerBuilder PROTOTYPE = new QueryRescorerBuilder(new MatchAllQueryBuilder()); - public static final float DEFAULT_RESCORE_QUERYWEIGHT = 1.0f; public static final float DEFAULT_QUERYWEIGHT = 1.0f; public static final QueryRescoreMode DEFAULT_SCORE_MODE = QueryRescoreMode.Total; @@ -78,6 +75,25 @@ public class QueryRescorerBuilder extends RescoreBuilder<QueryRescorerBuilder> { } /** + * Read from a stream. + */ + public QueryRescorerBuilder(StreamInput in) throws IOException { + super(in); + queryBuilder = in.readQuery(); + scoreMode = QueryRescoreMode.readFromStream(in); + rescoreQueryWeight = in.readFloat(); + queryWeight = in.readFloat(); + } + + @Override + public void doWriteTo(StreamOutput out) throws IOException { + out.writeQuery(queryBuilder); + scoreMode.writeTo(out); + out.writeFloat(rescoreQueryWeight); + out.writeFloat(queryWeight); + } + + /** * @return the query used for this rescore query */ public QueryBuilder<?> getRescoreQuery() { @@ -140,9 +156,9 @@ public class QueryRescorerBuilder extends RescoreBuilder<QueryRescorerBuilder> { builder.endObject(); } - public QueryRescorerBuilder fromXContent(QueryParseContext parseContext) throws IOException { - InnerBuilder innerBuilder = QUERY_RESCORE_PARSER.parse(parseContext.parser(), new InnerBuilder(), parseContext); - return innerBuilder.build(); + public static QueryRescorerBuilder fromXContent(QueryParseContext parseContext) throws IOException { + InnerBuilder innerBuilder = QUERY_RESCORE_PARSER.parse(parseContext.parser(), new InnerBuilder(), parseContext); + return innerBuilder.build(); } @Override @@ -182,23 +198,6 @@ public class QueryRescorerBuilder extends RescoreBuilder<QueryRescorerBuilder> { } @Override - public QueryRescorerBuilder doReadFrom(StreamInput in) throws IOException { - QueryRescorerBuilder rescorer = new QueryRescorerBuilder(in.readQuery()); - rescorer.setScoreMode(QueryRescoreMode.PROTOTYPE.readFrom(in)); - rescorer.setRescoreQueryWeight(in.readFloat()); - rescorer.setQueryWeight(in.readFloat()); - return rescorer; - } - - @Override - public void doWriteTo(StreamOutput out) throws IOException { - out.writeQuery(queryBuilder); - scoreMode.writeTo(out); - out.writeFloat(rescoreQueryWeight); - out.writeFloat(queryWeight); - } - - @Override public String getWriteableName() { return NAME; } @@ -208,7 +207,7 @@ public class QueryRescorerBuilder extends RescoreBuilder<QueryRescorerBuilder> { * for the constructor of {@link QueryRescorerBuilder}, but {@link ObjectParser} only * allows filling properties of an already constructed value. */ - private class InnerBuilder { + private static class InnerBuilder { private QueryBuilder<?> queryBuilder; private float rescoreQueryWeight = DEFAULT_RESCORE_QUERYWEIGHT; diff --git a/core/src/main/java/org/elasticsearch/search/rescore/RescoreBuilder.java b/core/src/main/java/org/elasticsearch/search/rescore/RescoreBuilder.java index 8dad07a543..3288538086 100644 --- a/core/src/main/java/org/elasticsearch/search/rescore/RescoreBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/rescore/RescoreBuilder.java @@ -46,6 +46,27 @@ public abstract class RescoreBuilder<RB extends RescoreBuilder<RB>> implements T private static ParseField WINDOW_SIZE_FIELD = new ParseField("window_size"); + /** + * Construct an empty RescoreBuilder. + */ + public RescoreBuilder() { + } + + /** + * Read from a stream. + */ + protected RescoreBuilder(StreamInput in) throws IOException { + windowSize = in.readOptionalVInt(); + } + + @Override + public final void writeTo(StreamOutput out) throws IOException { + out.writeOptionalVInt(this.windowSize); + doWriteTo(out); + } + + protected abstract void doWriteTo(StreamOutput out) throws IOException; + @SuppressWarnings("unchecked") public RB windowSize(int windowSize) { this.windowSize = windowSize; @@ -74,7 +95,7 @@ public abstract class RescoreBuilder<RB extends RescoreBuilder<RB>> implements T } else if (token == XContentParser.Token.START_OBJECT) { // we only have QueryRescorer at this point if (QueryRescorerBuilder.NAME.equals(fieldName)) { - rescorer = QueryRescorerBuilder.PROTOTYPE.fromXContent(parseContext); + rescorer = QueryRescorerBuilder.fromXContent(parseContext); } else { throw new ParsingException(parser.getTokenLocation(), "rescore doesn't support rescorer with name [" + fieldName + "]"); } @@ -129,23 +150,6 @@ public abstract class RescoreBuilder<RB extends RescoreBuilder<RB>> implements T } @Override - 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 { - doWriteTo(out); - out.writeOptionalVInt(this.windowSize); - } - - protected abstract void doWriteTo(StreamOutput out) throws IOException; - - @Override public final String toString() { try { XContentBuilder builder = XContentFactory.jsonBuilder(); diff --git a/core/src/main/java/org/elasticsearch/search/sort/FieldSortBuilder.java b/core/src/main/java/org/elasticsearch/search/sort/FieldSortBuilder.java index 414062c0cd..bbe6f12ff3 100644 --- a/core/src/main/java/org/elasticsearch/search/sort/FieldSortBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/sort/FieldSortBuilder.java @@ -42,7 +42,6 @@ import java.util.Objects; * A sort builder to sort based on a document field. */ public class FieldSortBuilder extends SortBuilder<FieldSortBuilder> { - public static final FieldSortBuilder PROTOTYPE = new FieldSortBuilder("_na_"); public static final String NAME = "field_sort"; public static final ParseField NESTED_PATH = new ParseField("nested_path"); public static final ParseField NESTED_FILTER = new ParseField("nested_filter"); @@ -96,6 +95,30 @@ public class FieldSortBuilder extends SortBuilder<FieldSortBuilder> { this.fieldName = fieldName; } + /** + * Read from a stream. + */ + public FieldSortBuilder(StreamInput in) throws IOException { + fieldName = in.readString(); + nestedFilter = in.readOptionalQuery(); + nestedPath = in.readOptionalString(); + missing = in.readGenericValue(); + order = in.readOptionalWriteable(SortOrder::readFromStream); + sortMode = in.readOptionalWriteable(SortMode::readFromStream); + unmappedType = in.readOptionalString(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(fieldName); + out.writeOptionalQuery(nestedFilter); + out.writeOptionalString(nestedPath); + out.writeGenericValue(missing); + out.writeOptionalWriteable(order); + out.writeOptionalWriteable(sortMode); + out.writeOptionalString(unmappedType); + } + /** Returns the document field this sort should be based on. */ public String getFieldName() { return this.fieldName; @@ -291,55 +314,16 @@ public class FieldSortBuilder extends SortBuilder<FieldSortBuilder> { return NAME; } - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeString(this.fieldName); - if (this.nestedFilter != null) { - out.writeBoolean(true); - out.writeQuery(this.nestedFilter); - } else { - out.writeBoolean(false); - } - out.writeOptionalString(this.nestedPath); - out.writeGenericValue(this.missing); - - if (this.order != null) { - out.writeBoolean(true); - this.order.writeTo(out); - } else { - out.writeBoolean(false); - } - - out.writeBoolean(this.sortMode != null); - if (this.sortMode != null) { - this.sortMode.writeTo(out); - } - out.writeOptionalString(this.unmappedType); - } - - @Override - public FieldSortBuilder readFrom(StreamInput in) throws IOException { - String fieldName = in.readString(); - FieldSortBuilder result = new FieldSortBuilder(fieldName); - if (in.readBoolean()) { - QueryBuilder<?> query = in.readQuery(); - result.setNestedFilter(query); - } - result.setNestedPath(in.readOptionalString()); - result.missing(in.readGenericValue()); - - if (in.readBoolean()) { - result.order(SortOrder.readOrderFrom(in)); - } - if (in.readBoolean()) { - result.sortMode(SortMode.PROTOTYPE.readFrom(in)); - } - result.unmappedType(in.readOptionalString()); - return result; - } - - @Override - public FieldSortBuilder fromXContent(QueryParseContext context, String fieldName) throws IOException { + /** + * Creates a new {@link FieldSortBuilder} from the query held by the {@link QueryParseContext} in + * {@link org.elasticsearch.common.xcontent.XContent} format. + * + * @param context the input parse context. The state on the parser contained in this context will be changed as a side effect of this + * method call + * @param fieldName in some sort syntax variations the field name precedes the xContent object that specifies further parameters, e.g. + * in '{ "foo": { "order" : "asc"} }'. When parsing the inner object, the field name can be passed in via this argument + */ + public static FieldSortBuilder fromXContent(QueryParseContext context, String fieldName) throws IOException { XContentParser parser = context.parser(); QueryBuilder<?> nestedFilter = null; diff --git a/core/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortBuilder.java b/core/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortBuilder.java index c6a63d5f08..1f5dccbdf4 100644 --- a/core/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortBuilder.java @@ -75,8 +75,6 @@ public class GeoDistanceSortBuilder extends SortBuilder<GeoDistanceSortBuilder> public static final ParseField NESTED_FILTER_FIELD = new ParseField("nested_filter"); public static final ParseField REVERSE_FORBIDDEN = new ParseField("reverse"); - public static final GeoDistanceSortBuilder PROTOTYPE = new GeoDistanceSortBuilder("_na_", -1, -1); - private final String fieldName; private final List<GeoPoint> points = new ArrayList<>(); @@ -150,6 +148,37 @@ public class GeoDistanceSortBuilder extends SortBuilder<GeoDistanceSortBuilder> } /** + * Read from a stream. + */ + @SuppressWarnings("unchecked") + public GeoDistanceSortBuilder(StreamInput in) throws IOException { + fieldName = in.readString(); + points.addAll((List<GeoPoint>) in.readGenericValue()); + geoDistance = GeoDistance.readGeoDistanceFrom(in); + unit = DistanceUnit.readFromStream(in); + order = SortOrder.readFromStream(in); + sortMode = in.readOptionalWriteable(SortMode::readFromStream); + nestedFilter = in.readOptionalQuery(); + nestedPath = in.readOptionalString(); + coerce = in.readBoolean(); + ignoreMalformed =in.readBoolean(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(fieldName); + out.writeGenericValue(points); + geoDistance.writeTo(out); + unit.writeTo(out); + order.writeTo(out); + out.writeOptionalWriteable(sortMode); + out.writeOptionalQuery(nestedFilter); + out.writeOptionalString(nestedPath); + out.writeBoolean(coerce); + out.writeBoolean(ignoreMalformed); + } + + /** * Returns the geo point like field the distance based sort operates on. * */ public String fieldName() { @@ -366,53 +395,16 @@ public class GeoDistanceSortBuilder extends SortBuilder<GeoDistanceSortBuilder> this.unit, this.sortMode, this.order, this.nestedFilter, this.nestedPath, this.coerce, this.ignoreMalformed); } - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeString(fieldName); - out.writeGenericValue(points); - - geoDistance.writeTo(out); - unit.writeTo(out); - order.writeTo(out); - out.writeBoolean(this.sortMode != null); - if (this.sortMode != null) { - sortMode.writeTo(out); - } - if (nestedFilter != null) { - out.writeBoolean(true); - out.writeQuery(nestedFilter); - } else { - out.writeBoolean(false); - } - out.writeOptionalString(nestedPath); - out.writeBoolean(coerce); - out.writeBoolean(ignoreMalformed); - } - - @Override - public GeoDistanceSortBuilder readFrom(StreamInput in) throws IOException { - String fieldName = in.readString(); - - ArrayList<GeoPoint> points = (ArrayList<GeoPoint>) in.readGenericValue(); - GeoDistanceSortBuilder result = new GeoDistanceSortBuilder(fieldName, points.toArray(new GeoPoint[points.size()])); - - result.geoDistance(GeoDistance.readGeoDistanceFrom(in)); - result.unit(DistanceUnit.readDistanceUnit(in)); - result.order(SortOrder.readOrderFrom(in)); - if (in.readBoolean()) { - result.sortMode = SortMode.PROTOTYPE.readFrom(in); - } - if (in.readBoolean()) { - result.setNestedFilter(in.readQuery()); - } - result.setNestedPath(in.readOptionalString()); - result.coerce(in.readBoolean()); - result.ignoreMalformed(in.readBoolean()); - return result; - } - - @Override - public GeoDistanceSortBuilder fromXContent(QueryParseContext context, String elementName) throws IOException { + /** + * Creates a new {@link GeoDistanceSortBuilder} from the query held by the {@link QueryParseContext} in + * {@link org.elasticsearch.common.xcontent.XContent} format. + * + * @param context the input parse context. The state on the parser contained in this context will be changed as a side effect of this + * method call + * @param elementName in some sort syntax variations the field name precedes the xContent object that specifies further parameters, e.g. + * in '{ "foo": { "order" : "asc"} }'. When parsing the inner object, the field name can be passed in via this argument + */ + public static GeoDistanceSortBuilder fromXContent(QueryParseContext context, String elementName) throws IOException { XContentParser parser = context.parser(); ParseFieldMatcher parseFieldMatcher = context.parseFieldMatcher(); String fieldName = null; diff --git a/core/src/main/java/org/elasticsearch/search/sort/ScoreSortBuilder.java b/core/src/main/java/org/elasticsearch/search/sort/ScoreSortBuilder.java index c222634ca0..fa4472fadf 100644 --- a/core/src/main/java/org/elasticsearch/search/sort/ScoreSortBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/sort/ScoreSortBuilder.java @@ -39,17 +39,31 @@ import java.util.Objects; public class ScoreSortBuilder extends SortBuilder<ScoreSortBuilder> { public static final String NAME = "_score"; - public static final ScoreSortBuilder PROTOTYPE = new ScoreSortBuilder(); + public static final ParseField REVERSE_FIELD = new ParseField("reverse"); public static final ParseField ORDER_FIELD = new ParseField("order"); private static final ParseField REVERSE_FORBIDDEN = new ParseField("reverse"); private static final SortField SORT_SCORE = new SortField(null, SortField.Type.SCORE); private static final SortField SORT_SCORE_REVERSE = new SortField(null, SortField.Type.SCORE, true); + /** + * Build a ScoreSortBuilder default to descending sort order. + */ public ScoreSortBuilder() { // order defaults to desc when sorting on the _score order(SortOrder.DESC); } + /** + * Read from a stream. + */ + public ScoreSortBuilder(StreamInput in) throws IOException { + order(SortOrder.readFromStream(in)); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + order.writeTo(out); + } @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { @@ -61,8 +75,16 @@ public class ScoreSortBuilder extends SortBuilder<ScoreSortBuilder> { return builder; } - @Override - public ScoreSortBuilder fromXContent(QueryParseContext context, String elementName) throws IOException { + /** + * Creates a new {@link ScoreSortBuilder} from the query held by the {@link QueryParseContext} in + * {@link org.elasticsearch.common.xcontent.XContent} format. + * + * @param context the input parse context. The state on the parser contained in this context will be changed as a side effect of this + * method call + * @param fieldName in some sort syntax variations the field name precedes the xContent object that specifies further parameters, e.g. + * in '{ "foo": { "order" : "asc"} }'. When parsing the inner object, the field name can be passed in via this argument + */ + public static ScoreSortBuilder fromXContent(QueryParseContext context, String fieldName) throws IOException { XContentParser parser = context.parser(); ParseFieldMatcher matcher = context.parseFieldMatcher(); @@ -112,17 +134,6 @@ public class ScoreSortBuilder extends SortBuilder<ScoreSortBuilder> { } @Override - public void writeTo(StreamOutput out) throws IOException { - order.writeTo(out); - } - - @Override - public ScoreSortBuilder readFrom(StreamInput in) throws IOException { - ScoreSortBuilder builder = new ScoreSortBuilder().order(SortOrder.readOrderFrom(in)); - return builder; - } - - @Override public String getWriteableName() { return NAME; } diff --git a/core/src/main/java/org/elasticsearch/search/sort/ScriptSortBuilder.java b/core/src/main/java/org/elasticsearch/search/sort/ScriptSortBuilder.java index b79eb6e214..2751d49751 100644 --- a/core/src/main/java/org/elasticsearch/search/sort/ScriptSortBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/sort/ScriptSortBuilder.java @@ -67,7 +67,6 @@ import java.util.Objects; public class ScriptSortBuilder extends SortBuilder<ScriptSortBuilder> { public static final String NAME = "_script"; - public static final ScriptSortBuilder PROTOTYPE = new ScriptSortBuilder(new Script("_na_"), ScriptSortType.STRING); public static final ParseField TYPE_FIELD = new ParseField("type"); public static final ParseField SCRIPT_FIELD = new ParseField("script"); public static final ParseField SORTMODE_FIELD = new ParseField("mode"); @@ -111,6 +110,28 @@ public class ScriptSortBuilder extends SortBuilder<ScriptSortBuilder> { } /** + * Read from a stream. + */ + public ScriptSortBuilder(StreamInput in) throws IOException { + script = Script.readScript(in); + type = ScriptSortType.readFromStream(in); + order = SortOrder.readFromStream(in); + sortMode = in.readOptionalWriteable(SortMode::readFromStream); + nestedPath = in.readOptionalString(); + nestedFilter = in.readOptionalQuery(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + script.writeTo(out); + type.writeTo(out); + order.writeTo(out); + out.writeOptionalWriteable(sortMode); + out.writeOptionalString(nestedPath); + out.writeOptionalQuery(nestedFilter); + } + + /** * Get the script used in this sort. */ public Script script() { @@ -198,8 +219,16 @@ public class ScriptSortBuilder extends SortBuilder<ScriptSortBuilder> { return builder; } - @Override - public ScriptSortBuilder fromXContent(QueryParseContext context, String elementName) throws IOException { + /** + * Creates a new {@link ScriptSortBuilder} from the query held by the {@link QueryParseContext} in + * {@link org.elasticsearch.common.xcontent.XContent} format. + * + * @param context the input parse context. The state on the parser contained in this context will be changed as a side effect of this + * method call + * @param elementName in some sort syntax variations the field name precedes the xContent object that specifies further parameters, e.g. + * in '{ "foo": { "order" : "asc"} }'. When parsing the inner object, the field name can be passed in via this argument + */ + public static ScriptSortBuilder fromXContent(QueryParseContext context, String elementName) throws IOException { ScriptParameterParser scriptParameterParser = new ScriptParameterParser(); XContentParser parser = context.parser(); ParseFieldMatcher parseField = context.parseFieldMatcher(); @@ -363,37 +392,6 @@ public class ScriptSortBuilder extends SortBuilder<ScriptSortBuilder> { } @Override - public void writeTo(StreamOutput out) throws IOException { - script.writeTo(out); - type.writeTo(out); - order.writeTo(out); - out.writeBoolean(sortMode != null); - if (sortMode != null) { - sortMode.writeTo(out); - } - out.writeOptionalString(nestedPath); - boolean hasNestedFilter = nestedFilter != null; - out.writeBoolean(hasNestedFilter); - if (hasNestedFilter) { - out.writeQuery(nestedFilter); - } - } - - @Override - public ScriptSortBuilder readFrom(StreamInput in) throws IOException { - ScriptSortBuilder builder = new ScriptSortBuilder(Script.readScript(in), ScriptSortType.PROTOTYPE.readFrom(in)); - builder.order(SortOrder.readOrderFrom(in)); - if (in.readBoolean()) { - builder.sortMode(SortMode.PROTOTYPE.readFrom(in)); - } - builder.nestedPath = in.readOptionalString(); - if (in.readBoolean()) { - builder.nestedFilter = in.readQuery(); - } - return builder; - } - - @Override public String getWriteableName() { return NAME; } @@ -404,15 +402,15 @@ public class ScriptSortBuilder extends SortBuilder<ScriptSortBuilder> { /** script sort for a numeric value **/ NUMBER; - static ScriptSortType PROTOTYPE = STRING; - @Override public void writeTo(final StreamOutput out) throws IOException { out.writeVInt(ordinal()); } - @Override - public ScriptSortType readFrom(final StreamInput in) throws IOException { + /** + * Read from a stream. + */ + static ScriptSortType readFromStream(final StreamInput in) throws IOException { int ordinal = in.readVInt(); if (ordinal < 0 || ordinal >= values().length) { throw new IOException("Unknown ScriptSortType ordinal [" + ordinal + "]"); diff --git a/core/src/main/java/org/elasticsearch/search/sort/SortBuilder.java b/core/src/main/java/org/elasticsearch/search/sort/SortBuilder.java index e007ac7736..ee6af01c93 100644 --- a/core/src/main/java/org/elasticsearch/search/sort/SortBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/sort/SortBuilder.java @@ -24,7 +24,6 @@ import org.apache.lucene.search.Sort; import org.apache.lucene.search.SortField; import org.apache.lucene.search.join.BitSetProducer; import org.elasticsearch.action.support.ToXContentToBytes; -import org.elasticsearch.common.Nullable; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.io.stream.NamedWriteable; import org.elasticsearch.common.lucene.search.Queries; @@ -55,34 +54,18 @@ public abstract class SortBuilder<T extends SortBuilder<?>> extends ToXContentTo protected SortOrder order = SortOrder.ASC; public static final ParseField ORDER_FIELD = new ParseField("order"); - private static final Map<String, SortBuilder<?>> PARSERS; - + private static final Map<String, Parser<?>> PARSERS; static { - Map<String, SortBuilder<?>> parsers = new HashMap<>(); - parsers.put(ScriptSortBuilder.NAME, ScriptSortBuilder.PROTOTYPE); - parsers.put(GeoDistanceSortBuilder.NAME, new GeoDistanceSortBuilder("_na_", -1, -1)); - parsers.put(GeoDistanceSortBuilder.ALTERNATIVE_NAME, new GeoDistanceSortBuilder("_na_", -1, -1)); - parsers.put(ScoreSortBuilder.NAME, ScoreSortBuilder.PROTOTYPE); + Map<String, Parser<?>> parsers = new HashMap<>(); + parsers.put(ScriptSortBuilder.NAME, ScriptSortBuilder::fromXContent); + parsers.put(GeoDistanceSortBuilder.NAME, GeoDistanceSortBuilder::fromXContent); + parsers.put(GeoDistanceSortBuilder.ALTERNATIVE_NAME, GeoDistanceSortBuilder::fromXContent); + parsers.put(ScoreSortBuilder.NAME, ScoreSortBuilder::fromXContent); + // FieldSortBuilder gets involved if the user specifies a name that isn't one of these. PARSERS = unmodifiableMap(parsers); } /** - * Creates a new {@link SortBuilder} from the query held by the {@link QueryParseContext} - * in {@link org.elasticsearch.common.xcontent.XContent} format - * - * @param parseContext - * the input parse context. The state on the parser contained in - * this context will be changed as a side effect of this method call - * @param fieldName - * in some sort syntax variations the field name precedes the xContent object that - * specifies further parameters, e.g. in '{ "foo": { "order" : "asc"} }'. When - * parsing the inner object, the field name can be passed in via this argument - * - * @return the new sort builder instance - */ - protected abstract T fromXContent(QueryParseContext parseContext, @Nullable String fieldName) throws IOException; - - /** * Create a @link {@link SortField} from this builder. */ protected abstract SortField build(QueryShardContext context) throws IOException; @@ -153,7 +136,7 @@ public abstract class SortBuilder<T extends SortBuilder<?>> extends ToXContentTo if (PARSERS.containsKey(fieldName)) { sortFields.add(PARSERS.get(fieldName).fromXContent(context, fieldName)); } else { - sortFields.add(FieldSortBuilder.PROTOTYPE.fromXContent(context, fieldName)); + sortFields.add(FieldSortBuilder.fromXContent(context, fieldName)); } } } @@ -218,4 +201,9 @@ public abstract class SortBuilder<T extends SortBuilder<?>> extends ToXContentTo } return nested; } + + @FunctionalInterface + private interface Parser<T extends SortBuilder<?>> { + T fromXContent(QueryParseContext context, String elementName) throws IOException; + } } diff --git a/core/src/main/java/org/elasticsearch/search/sort/SortMode.java b/core/src/main/java/org/elasticsearch/search/sort/SortMode.java index 2f6ce9401d..c6b3e1b10b 100644 --- a/core/src/main/java/org/elasticsearch/search/sort/SortMode.java +++ b/core/src/main/java/org/elasticsearch/search/sort/SortMode.java @@ -50,15 +50,12 @@ public enum SortMode implements Writeable<SortMode> { /** Use the median of all values as sort value. Only applicable for number based array fields. **/ MEDIAN; - static SortMode PROTOTYPE = MIN; - @Override public void writeTo(final StreamOutput out) throws IOException { out.writeVInt(ordinal()); } - @Override - public SortMode readFrom(final StreamInput in) throws IOException { + public static SortMode readFromStream(StreamInput in) throws IOException { int ordinal = in.readVInt(); if (ordinal < 0 || ordinal >= values().length) { throw new IOException("Unknown SortMode ordinal [" + ordinal + "]"); diff --git a/core/src/main/java/org/elasticsearch/search/sort/SortOrder.java b/core/src/main/java/org/elasticsearch/search/sort/SortOrder.java index 73e5ac5524..a84a456775 100644 --- a/core/src/main/java/org/elasticsearch/search/sort/SortOrder.java +++ b/core/src/main/java/org/elasticsearch/search/sort/SortOrder.java @@ -50,11 +50,8 @@ public enum SortOrder implements Writeable<SortOrder> { return "desc"; } }; - - private static final SortOrder PROTOTYPE = ASC; - @Override - public SortOrder readFrom(StreamInput in) throws IOException { + static SortOrder readFromStream(StreamInput in) throws IOException { int ordinal = in.readVInt(); if (ordinal < 0 || ordinal >= values().length) { throw new IOException("Unknown SortOrder ordinal [" + ordinal + "]"); @@ -62,10 +59,6 @@ public enum SortOrder implements Writeable<SortOrder> { return values()[ordinal]; } - public static SortOrder readOrderFrom(StreamInput in) throws IOException { - return PROTOTYPE.readFrom(in); - } - @Override public void writeTo(StreamOutput out) throws IOException { out.writeVInt(this.ordinal()); |