diff options
Diffstat (limited to 'core/src/main/java/org/elasticsearch/search/sort')
7 files changed, 151 insertions, 188 deletions
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()); |