Cut nested and reverse_nested aggregations to registerAggregation

and remove their PROTOTYPES.

Relates to #17085
This commit is contained in:
Nik Everett 2016-04-14 16:25:49 -04:00
parent eb4ba38032
commit b5a58ece41
5 changed files with 118 additions and 171 deletions

View File

@ -120,8 +120,8 @@ import org.elasticsearch.search.aggregations.bucket.missing.InternalMissing;
import org.elasticsearch.search.aggregations.bucket.missing.MissingParser;
import org.elasticsearch.search.aggregations.bucket.nested.InternalNested;
import org.elasticsearch.search.aggregations.bucket.nested.InternalReverseNested;
import org.elasticsearch.search.aggregations.bucket.nested.NestedParser;
import org.elasticsearch.search.aggregations.bucket.nested.ReverseNestedParser;
import org.elasticsearch.search.aggregations.bucket.nested.NestedAggregatorBuilder;
import org.elasticsearch.search.aggregations.bucket.nested.ReverseNestedAggregatorBuilder;
import org.elasticsearch.search.aggregations.bucket.range.InternalRange;
import org.elasticsearch.search.aggregations.bucket.range.RangeAggregatorBuilder;
import org.elasticsearch.search.aggregations.bucket.range.RangeParser;
@ -474,8 +474,9 @@ public class SearchModule extends AbstractModule {
DateHistogramAggregatorBuilder.AGGREGATION_NAME_FIELD);
registerAggregatorParser(new GeoDistanceParser());
registerAggregatorParser(new GeoHashGridParser());
registerAggregatorParser(new NestedParser());
registerAggregatorParser(new ReverseNestedParser());
registerAggregation(NestedAggregatorBuilder::new, NestedAggregatorBuilder::parse, NestedAggregatorBuilder.AGGREGATION_FIELD_NAME);
registerAggregation(ReverseNestedAggregatorBuilder::new, ReverseNestedAggregatorBuilder::parse,
ReverseNestedAggregatorBuilder.AGGREGATION_NAME_FIELD);
registerAggregatorParser(new TopHitsParser());
registerAggregatorParser(new GeoBoundsParser());
registerAggregatorParser(new GeoCentroidParser());

View File

@ -19,20 +19,24 @@
package org.elasticsearch.search.aggregations.bucket.nested;
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.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.search.aggregations.AggregatorBuilder;
import org.elasticsearch.search.aggregations.AggregatorFactory;
import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
import org.elasticsearch.search.aggregations.AggregatorFactory;
import org.elasticsearch.search.aggregations.support.AggregationContext;
import java.io.IOException;
import java.util.Objects;
public class NestedAggregatorBuilder extends AggregatorBuilder<NestedAggregatorBuilder> {
static final NestedAggregatorBuilder PROTOTYPE = new NestedAggregatorBuilder("", "");
public static final String NAME = InternalNested.TYPE.name();
public static final ParseField AGGREGATION_FIELD_NAME = new ParseField(NAME);
private final String path;
@ -51,6 +55,24 @@ public class NestedAggregatorBuilder extends AggregatorBuilder<NestedAggregatorB
this.path = path;
}
/**
* Read from a stream.
*/
public NestedAggregatorBuilder(StreamInput in) throws IOException {
super(in, InternalNested.TYPE);
path = in.readString();
}
@Override
protected void doWriteTo(StreamOutput out) throws IOException {
out.writeString(path);
}
@Override
protected boolean usesNewStyleSerialization() {
return true;
}
/**
* Get the path to use for this nested aggregation.
*/
@ -72,17 +94,35 @@ public class NestedAggregatorBuilder extends AggregatorBuilder<NestedAggregatorB
return builder;
}
@Override
protected NestedAggregatorBuilder doReadFrom(String name, StreamInput in) throws IOException {
String path = in.readString();
NestedAggregatorBuilder factory = new NestedAggregatorBuilder(name, path);
return factory;
public static NestedAggregatorBuilder parse(String aggregationName, QueryParseContext context) throws IOException {
String path = null;
XContentParser.Token token;
String currentFieldName = null;
XContentParser parser = context.parser();
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.VALUE_STRING) {
if (context.getParseFieldMatcher().match(currentFieldName, NestedAggregator.PATH_FIELD)) {
path = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(),
"Unknown key for a " + token + " in [" + aggregationName + "]: [" + currentFieldName + "].");
}
} else {
throw new ParsingException(parser.getTokenLocation(), "Unexpected token " + token + " in [" + aggregationName + "].");
}
}
if (path == null) {
// "field" doesn't exist, so we fall back to the context of the ancestors
throw new ParsingException(parser.getTokenLocation(), "Missing [path] field for nested aggregation [" + aggregationName + "]");
}
return new NestedAggregatorBuilder(aggregationName, path);
}
@Override
protected void doWriteTo(StreamOutput out) throws IOException {
out.writeString(path);
}
@Override
protected int doHashCode() {
@ -94,4 +134,9 @@ public class NestedAggregatorBuilder extends AggregatorBuilder<NestedAggregatorB
NestedAggregatorBuilder other = (NestedAggregatorBuilder) obj;
return Objects.equals(path, other.path);
}
@Override
public String getWriteableName() {
return NAME;
}
}

View File

@ -1,72 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.search.aggregations.bucket.nested;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.search.aggregations.Aggregator;
import java.io.IOException;
/**
*
*/
public class NestedParser implements Aggregator.Parser {
@Override
public String type() {
return InternalNested.TYPE.name();
}
@Override
public NestedAggregatorBuilder parse(String aggregationName, QueryParseContext context) throws IOException {
String path = null;
XContentParser.Token token;
String currentFieldName = null;
XContentParser parser = context.parser();
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.VALUE_STRING) {
if (context.getParseFieldMatcher().match(currentFieldName, NestedAggregator.PATH_FIELD)) {
path = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(),
"Unknown key for a " + token + " in [" + aggregationName + "]: [" + currentFieldName + "].");
}
} else {
throw new ParsingException(parser.getTokenLocation(), "Unexpected token " + token + " in [" + aggregationName + "].");
}
}
if (path == null) {
// "field" doesn't exist, so we fall back to the context of the ancestors
throw new ParsingException(parser.getTokenLocation(), "Missing [path] field for nested aggregation [" + aggregationName + "]");
}
return new NestedAggregatorBuilder(aggregationName, path);
}
@Override
public NestedAggregatorBuilder getFactoryPrototypes() {
return NestedAggregatorBuilder.PROTOTYPE;
}
}

View File

@ -19,20 +19,24 @@
package org.elasticsearch.search.aggregations.bucket.nested;
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.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.search.aggregations.AggregatorBuilder;
import org.elasticsearch.search.aggregations.AggregatorFactory;
import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
import org.elasticsearch.search.aggregations.AggregatorFactory;
import org.elasticsearch.search.aggregations.support.AggregationContext;
import java.io.IOException;
import java.util.Objects;
public class ReverseNestedAggregatorBuilder extends AggregatorBuilder<ReverseNestedAggregatorBuilder> {
static final ReverseNestedAggregatorBuilder PROTOTYPE = new ReverseNestedAggregatorBuilder("");
public static final String NAME = InternalReverseNested.TYPE.name();
public static final ParseField AGGREGATION_NAME_FIELD = new ParseField(NAME);
private String path;
@ -40,6 +44,24 @@ public class ReverseNestedAggregatorBuilder extends AggregatorBuilder<ReverseNes
super(name, InternalReverseNested.TYPE);
}
/**
* Read from a stream.
*/
public ReverseNestedAggregatorBuilder(StreamInput in) throws IOException {
super(in, InternalReverseNested.TYPE);
path = in.readOptionalString();
}
@Override
protected void doWriteTo(StreamOutput out) throws IOException {
out.writeOptionalString(path);
}
@Override
protected boolean usesNewStyleSerialization() {
return true;
}
/**
* Set the path to use for this nested aggregation. The path must match
* the path to a nested object in the mappings. If it is not specified
@ -76,17 +98,35 @@ public class ReverseNestedAggregatorBuilder extends AggregatorBuilder<ReverseNes
return builder;
}
@Override
protected ReverseNestedAggregatorBuilder doReadFrom(String name, StreamInput in) throws IOException {
ReverseNestedAggregatorBuilder factory = new ReverseNestedAggregatorBuilder(name);
factory.path = in.readOptionalString();
public static ReverseNestedAggregatorBuilder parse(String aggregationName, QueryParseContext context) throws IOException {
String path = null;
XContentParser.Token token;
String currentFieldName = null;
XContentParser parser = context.parser();
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.VALUE_STRING) {
if ("path".equals(currentFieldName)) {
path = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(),
"Unknown key for a " + token + " in [" + aggregationName + "]: [" + currentFieldName + "].");
}
} else {
throw new ParsingException(parser.getTokenLocation(), "Unexpected token " + token + " in [" + aggregationName + "].");
}
}
ReverseNestedAggregatorBuilder factory = new ReverseNestedAggregatorBuilder(
aggregationName);
if (path != null) {
factory.path(path);
}
return factory;
}
@Override
protected void doWriteTo(StreamOutput out) throws IOException {
out.writeOptionalString(path);
}
@Override
protected int doHashCode() {
@ -98,4 +138,9 @@ public class ReverseNestedAggregatorBuilder extends AggregatorBuilder<ReverseNes
ReverseNestedAggregatorBuilder other = (ReverseNestedAggregatorBuilder) obj;
return Objects.equals(path, other.path);
}
@Override
public String getWriteableName() {
return NAME;
}
}

View File

@ -1,72 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.search.aggregations.bucket.nested;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.search.aggregations.Aggregator;
import java.io.IOException;
/**
*
*/
public class ReverseNestedParser implements Aggregator.Parser {
@Override
public String type() {
return InternalReverseNested.TYPE.name();
}
@Override
public ReverseNestedAggregatorBuilder parse(String aggregationName, QueryParseContext context) throws IOException {
String path = null;
XContentParser.Token token;
String currentFieldName = null;
XContentParser parser = context.parser();
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.VALUE_STRING) {
if ("path".equals(currentFieldName)) {
path = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(),
"Unknown key for a " + token + " in [" + aggregationName + "]: [" + currentFieldName + "].");
}
} else {
throw new ParsingException(parser.getTokenLocation(), "Unexpected token " + token + " in [" + aggregationName + "].");
}
}
ReverseNestedAggregatorBuilder factory = new ReverseNestedAggregatorBuilder(
aggregationName);
if (path != null) {
factory.path(path);
}
return factory;
}
@Override
public ReverseNestedAggregatorBuilder getFactoryPrototypes() {
return ReverseNestedAggregatorBuilder.PROTOTYPE;
}
}