Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions core/src/main/java/org/elasticsearch/common/ParseField.java
Original file line number Diff line number Diff line change
Expand Up @@ -160,5 +160,9 @@ public static class CommonFields {
public static final ParseField FORMAT = new ParseField("format");
public static final ParseField MISSING = new ParseField("missing");
public static final ParseField TIME_ZONE = new ParseField("time_zone");
public static final ParseField KEYED = new ParseField("keyed");
public static final ParseField OFFSET = new ParseField("offset");
public static final ParseField MIN_DOC_COUNT = new ParseField("min_doc_count");
public static final ParseField ORDER = new ParseField("order");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
package org.elasticsearch.common.xcontent;

import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.xcontent.XContentParser.Token;
import org.elasticsearch.rest.action.search.RestSearchAction;

import java.io.IOException;
import java.util.Locale;
Expand Down Expand Up @@ -107,4 +109,26 @@ public static Object parseStoredFieldsValue(XContentParser parser) throws IOExce
}
return value;
}

public static <T> T parseTypedKeysObject(XContentParser parser,
String delimiter,
Class<T> objectClass) throws IOException {
ensureExpectedToken(XContentParser.Token.FIELD_NAME,
parser.currentToken(), parser::getTokenLocation);

String currentFieldName = parser.currentName();
if (Strings.hasLength(currentFieldName)) {
int start = currentFieldName.indexOf(delimiter);
if (start > 0) {
String type = currentFieldName.substring(0, start);
String name = currentFieldName.substring(start + 1);
return parser.namedObject(objectClass, type, name);
}
}
throw new ParsingException(parser.getTokenLocation(), "Cannot parse object of class "
+ "[" + objectClass.getSimpleName() + "] without type information. Set ["
+ RestSearchAction.TYPED_KEYS_PARAM + "] parameter on the request to ensure the "
+ "type information is added to the response output");

}
}
126 changes: 121 additions & 5 deletions core/src/main/java/org/elasticsearch/search/DocValueFormat.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.network.InetAddresses;
import org.elasticsearch.common.network.NetworkAddress;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.joda.time.DateTimeZone;

import java.io.IOException;
Expand All @@ -43,8 +46,12 @@
import java.util.Objects;
import java.util.function.LongSupplier;

import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken;
import static org.elasticsearch.common.xcontent.XContentParserUtils.throwUnknownField;
import static org.elasticsearch.common.xcontent.XContentParserUtils.throwUnknownToken;

/** A formatter for values as returned by the fielddata/doc-values APIs. */
public interface DocValueFormat extends NamedWriteable {
public interface DocValueFormat extends NamedWriteable, ToXContentObject {

/** Format a long value. This is used by terms and histogram aggregations
* to format keys for fields that use longs as a doc value representation
Expand Down Expand Up @@ -75,9 +82,11 @@ public interface DocValueFormat extends NamedWriteable {

DocValueFormat RAW = new DocValueFormat() {

static final String NAME = "raw";

@Override
public String getWriteableName() {
return "raw";
return NAME;
}

@Override
Expand Down Expand Up @@ -119,6 +128,11 @@ public double parseDouble(String value, boolean roundUp, LongSupplier now) {
public BytesRef parseBytesRef(String value) {
return new BytesRef(value);
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject().startObject(NAME).endObject().endObject();
}
};

final class DateTime implements DocValueFormat {
Expand Down Expand Up @@ -179,13 +193,46 @@ public double parseDouble(String value, boolean roundUp, LongSupplier now) {
public BytesRef parseBytesRef(String value) {
throw new UnsupportedOperationException();
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.startObject(NAME);
builder.field("pattern", formatter.format());
builder.field("timezone", timeZone.getID());
builder.endObject();
return builder.endObject();
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}

//TODO tlrx This is wrong
DateTime that = (DateTime) o;
return Objects.equals(formatter.format(), that.formatter.format())
&& Objects.equals(formatter.locale(), that.formatter.locale())
&& Objects.equals(timeZone, that.timeZone);
}

@Override
public int hashCode() {
return Objects.hash(formatter.format(), formatter.locale(), timeZone);
}
}

DocValueFormat GEOHASH = new DocValueFormat() {

static final String NAME = "geo_hash";

@Override
public String getWriteableName() {
return "geo_hash";
return NAME;
}

@Override
Expand Down Expand Up @@ -221,13 +268,20 @@ public double parseDouble(String value, boolean roundUp, LongSupplier now) {
public BytesRef parseBytesRef(String value) {
throw new UnsupportedOperationException();
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject().startObject(NAME).endObject().endObject();
}
};

DocValueFormat BOOLEAN = new DocValueFormat() {

static final String NAME = "bool";

@Override
public String getWriteableName() {
return "bool";
return NAME;
}

@Override
Expand Down Expand Up @@ -269,13 +323,20 @@ public double parseDouble(String value, boolean roundUp, LongSupplier now) {
public BytesRef parseBytesRef(String value) {
throw new UnsupportedOperationException();
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject().startObject(NAME).endObject().endObject();
}
};

DocValueFormat IP = new DocValueFormat() {

static final String NAME = "ip";

@Override
public String getWriteableName() {
return "ip";
return NAME;
}

@Override
Expand Down Expand Up @@ -313,6 +374,11 @@ public double parseDouble(String value, boolean roundUp, LongSupplier now) {
public BytesRef parseBytesRef(String value) {
return new BytesRef(InetAddressPoint.encode(InetAddresses.forString(value)));
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject().startObject(NAME).endObject().endObject();
}
};

final class Decimal implements DocValueFormat {
Expand Down Expand Up @@ -393,5 +459,55 @@ public double parseDouble(String value, boolean roundUp, LongSupplier now) {
public BytesRef parseBytesRef(String value) {
throw new UnsupportedOperationException();
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.startObject(NAME);
builder.field("pattern", pattern);
builder.endObject();
return builder.endObject();
}
}

static DocValueFormat fromXContent(XContentParser parser) throws IOException {
XContentParser.Token token = parser.nextToken();
ensureExpectedToken(XContentParser.Token.START_OBJECT, token, parser::getTokenLocation);

token = parser.nextToken();
ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation);

DocValueFormat docValueFormat = null;

String currentFieldName = parser.currentName();
if ("raw".equals(currentFieldName)) {
ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation);
ensureExpectedToken(XContentParser.Token.END_OBJECT, parser.nextToken(), parser::getTokenLocation);
docValueFormat = DocValueFormat.RAW;

} else if ("date_time".equals(currentFieldName)) {
ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation);

String pattern = null, timezone = null;
while((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token.isValue()) {
if ("pattern".equals(currentFieldName)) {
pattern = parser.text();
} else if ("timezone".equals(currentFieldName)) {
timezone = parser.text();
} else {
throwUnknownField(currentFieldName, parser.getTokenLocation());
}
} else {
throwUnknownToken(token, parser.getTokenLocation());
}
}
docValueFormat = new DateTime(Joda.forPattern(pattern), DateTimeZone.forID(timezone));
}

ensureExpectedToken(XContentParser.Token.END_OBJECT, parser.nextToken(), parser::getTokenLocation);
return docValueFormat;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.rest.action.search.RestSearchAction;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
Expand All @@ -35,6 +36,11 @@
import java.util.Map;
import java.util.Objects;

import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken;
import static org.elasticsearch.common.xcontent.XContentParserUtils.parseTypedKeysObject;
import static org.elasticsearch.common.xcontent.XContentParserUtils.throwUnknownField;
import static org.elasticsearch.common.xcontent.XContentParserUtils.throwUnknownToken;

/**
* An internal implementation of {@link Aggregation}. Serves as a base class for all aggregation implementations.
*/
Expand Down Expand Up @@ -253,4 +259,49 @@ public static final class CommonFields extends ParseField.CommonFields {
public static final ParseField TO = new ParseField("to");
public static final ParseField TO_AS_STRING = new ParseField("to_as_string");
}

public static InternalAggregation fromXContent(XContentParser parser) throws IOException {
return parseTypedKeysObject(parser, TYPED_KEYS_DELIMITER, InternalAggregation.class);
}

protected static void parseCommonToXContent(XContentParser parser, Builder builder) throws IOException {
XContentParser.Token token = parser.currentToken();
ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation);

String currentFieldName = parser.currentName();
token = parser.nextToken();

if (token == XContentParser.Token.START_OBJECT) {
if (CommonFields.META.getPreferredName().equals(currentFieldName)) {
builder.setMetaData(parser.map());
} else {
throwUnknownField(currentFieldName, parser.getTokenLocation());
}
} else {
throwUnknownToken(token, parser.getTokenLocation());
}
}

public abstract static class Builder {
protected String name;
protected Map<String, Object> metaData;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Map<String, Object> getMetaData() {
return metaData;
}

public void setMetaData(Map<String, Object> metaData) {
this.metaData = metaData;
}

public abstract InternalAggregation build();
}
}
Loading