-
Notifications
You must be signed in to change notification settings - Fork 25.2k
Improving parsing of sigma param for Extended Stats Bucket Aggregation #17562
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,7 +27,6 @@ | |
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; | ||
|
||
import java.io.IOException; | ||
import java.text.ParseException; | ||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
|
@@ -53,7 +52,7 @@ public final BucketMetricsPipelineAggregatorBuilder<?> parse(String pipelineAggr | |
String[] bucketsPaths = null; | ||
String format = null; | ||
GapPolicy gapPolicy = null; | ||
Map<String, Object> leftover = new HashMap<>(5); | ||
Map<String, Object> params = new HashMap<>(5); | ||
|
||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { | ||
if (token == XContentParser.Token.FIELD_NAME) { | ||
|
@@ -66,7 +65,7 @@ public final BucketMetricsPipelineAggregatorBuilder<?> parse(String pipelineAggr | |
} else if (context.getParseFieldMatcher().match(currentFieldName, GAP_POLICY)) { | ||
gapPolicy = GapPolicy.parse(context, parser.text(), parser.getTokenLocation()); | ||
} else { | ||
leftover.put(currentFieldName, parser.text()); | ||
parseToken(pipelineAggregatorName, parser, context, currentFieldName, token, params); | ||
} | ||
} else if (token == XContentParser.Token.START_ARRAY) { | ||
if (context.getParseFieldMatcher().match(currentFieldName, BUCKETS_PATH)) { | ||
|
@@ -77,10 +76,10 @@ public final BucketMetricsPipelineAggregatorBuilder<?> parse(String pipelineAggr | |
} | ||
bucketsPaths = paths.toArray(new String[paths.size()]); | ||
} else { | ||
leftover.put(currentFieldName, parser.list()); | ||
parseToken(pipelineAggregatorName, parser, context, currentFieldName, token, params); | ||
} | ||
} else { | ||
leftover.put(currentFieldName, parser.objectText()); | ||
parseToken(pipelineAggregatorName, parser, context, currentFieldName, token, params); | ||
} | ||
} | ||
|
||
|
@@ -89,30 +88,32 @@ public final BucketMetricsPipelineAggregatorBuilder<?> parse(String pipelineAggr | |
"Missing required field [" + BUCKETS_PATH.getPreferredName() + "] for aggregation [" + pipelineAggregatorName + "]"); | ||
} | ||
|
||
BucketMetricsPipelineAggregatorBuilder<?> factory = null; | ||
try { | ||
factory = buildFactory(pipelineAggregatorName, bucketsPaths[0], leftover); | ||
if (format != null) { | ||
factory.format(format); | ||
} | ||
if (gapPolicy != null) { | ||
factory.gapPolicy(gapPolicy); | ||
} | ||
} catch (ParseException exception) { | ||
throw new ParsingException(parser.getTokenLocation(), | ||
"Could not parse settings for aggregation [" + pipelineAggregatorName + "].", exception); | ||
BucketMetricsPipelineAggregatorBuilder<?> factory = buildFactory(pipelineAggregatorName, bucketsPaths[0], params); | ||
if (format != null) { | ||
factory.format(format); | ||
} | ||
|
||
if (leftover.size() > 0) { | ||
throw new ParsingException(parser.getTokenLocation(), | ||
"Unexpected tokens " + leftover.keySet() + " in [" + pipelineAggregatorName + "]."); | ||
if (gapPolicy != null) { | ||
factory.gapPolicy(gapPolicy); | ||
} | ||
|
||
assert(factory != null); | ||
|
||
return factory; | ||
} | ||
|
||
protected abstract BucketMetricsPipelineAggregatorBuilder<?> buildFactory(String pipelineAggregatorName, String bucketsPaths, | ||
Map<String, Object> unparsedParams) throws ParseException; | ||
Map<String, Object> params); | ||
|
||
protected boolean token(XContentParser parser, QueryParseContext context, String field, | ||
XContentParser.Token token, Map<String, Object> params) throws IOException { | ||
return false; | ||
} | ||
|
||
private void parseToken(String aggregationName, XContentParser parser, QueryParseContext context, String currentFieldName, | ||
XContentParser.Token currentToken, Map<String, Object> params) throws IOException { | ||
if (token(parser, context, currentFieldName, currentToken, params) == false) { | ||
throw new ParsingException(parser.getTokenLocation(), | ||
"Unexpected token " + currentToken + " [" + currentFieldName + "] in [" + aggregationName + "]"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think BuildFactory should be allowed to throw a ParseException since subclasses should have the ability to throw it if there is a problem with creating the builder at this point There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is ParseException right choice in this case? |
||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This reason for using the leftover map here is so we can provide all the incorrect fields in one error message rather than reporting one error at a time and making the user potentially have to iterate multiple times to fix all their errors. Would you be able to revert these changes here so we again have these errors all reported in one go?
In the future I would like to extend this to the entire request and all parsing errors so we report all problems with the request at once.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually looking more at the changes you have made I see that you have made the code more like the other aggregation parsers so I think I would like to keep these changes and implement the above in another way in the future.