Skip to content

Conversation

@javanna
Copy link
Member

@javanna javanna commented May 16, 2017

SearchResponse#fromXContent allows to parse a search response, including search hits, aggregations, suggestions and profile results. Only the aggs that we can parse today are supported (which means all of them but a couple that are left to support). SearchResponseTests reuses the existing test infra to randomize aggregations, suggestions and profile response.

This PR contains some of the changes proposed with #22533 and add extensive tests for it based on the existing test infra for parsing responses.

Relates to #23331

SearchResponse#fromXContent allows to parse a search response, including search hits, aggregations, suggestions and profile results. Only the aggs that we can parse today are supported (which means all of them but a couple that are left to support). SearchResponseTests reuses the existing test infra to randomize aggregations, suggestions and profile response.

Relates to elastic#23331
@javanna javanna force-pushed the enhancement/search_response_parsing branch from 1a46f86 to b8ad84e Compare May 16, 2017 18:22

public static SearchResponse fromXContent(XContentParser parser) throws IOException {
XContentParser.Token token;
ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.currentToken(), parser::getTokenLocation);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can you move the ensureExpectedToken() first?

XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation);
SearchResponse parsed = SearchResponse.fromXContent(parser);
// check that we at least get the same number of shardFailures
assertEquals(response.getShardFailures().length, parsed.getShardFailures().length);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have some tests that create a failure instance and its expected instance, maybe we could have something similar here and use ElasticsearchExceptionTests.randomExceptions()?

boolean humanReadable = randomBoolean();
final ToXContent.Params params = new ToXContent.MapParams(singletonMap(RestSearchAction.TYPED_KEYS_PARAM, "true"));
BytesReference originalBytes = toShuffledXContent(response, xcontentType, params, humanReadable);
XContentParser parser = createParser(xcontentType.xContent(), originalBytes);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use try-with-resources here so that resources are released asap?

@javanna
Copy link
Member Author

javanna commented May 17, 2017

@tlrx can you please check if my latest commit addresses your concerns?

Copy link
Member

@cbuescher cbuescher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@javanna left one general question about ignoring unknown fields in the parser and a small nit about a test, otherwise LGTM

} else if (NUM_REDUCE_PHASES.match(currentFieldName)) {
numReducePhases = parser.intValue();
} else {
throwUnknownField(currentFieldName, parser.getTokenLocation());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We started being lenient with other parts of the response in order to allow new fields in the future to work with an older client. Should we also do this on this level? This applies to all similar checks in this PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we are free to do whatever we want to do until we test that leniency. I went for using throwUnknownField as that one may one day conditionally throw. Or maybe we have to remove it. But once we test this behaviour, we will have to go back to each parsing method and check that we do the right thing

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fine with me.

+ "\"max_score\":1.5,"
+ "\"hits\":[{\"_type\":\"type\",\"_id\":\"id1\",\"_score\":2.0}]"
+ "}"
+ "}", Strings.toString(response));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although I liked it at first, I'm starting to doubt the usefulness of these tests. And formatting makes it unreadable. If we keep it, can you change this to something like:

StringBuilder expectedString = new StringBuilder();
        expectedString.append("{");
        {
            expectedString.append("\"took\":0,");
            expectedString.append("\"timed_out\":false,");
            expectedString.append("\"_shards\":");
            {
                expectedString.append("{\"total\":0,");
                expectedString.append("\"successful\":0,");
                expectedString.append("\"failed\":0},");
            }
            expectedString.append("\"hits\":");
            {
                expectedString.append("{\"total\":100,");
                expectedString.append("\"max_score\":1.5,");
                expectedString.append("\"hits\":[{\"_type\":\"type\",\"_id\":\"id1\",\"_score\":2.0}]}");
            }
        }
        expectedString.append("}");
        assertEquals(expectedString.toString(), Strings.toString(response));

That should be more robust against auto-formatting.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't find it much more readable when using a string builder though :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe not much, but not even a tiny bit better?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a suggestion, I don't mind if we remove it here entirely. I used to like those tests because they show how a typical xContent output of those classes looks like. But with these large ones its kind of debatable whether it is useful.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reformatted, was just a copy paste, thanks for doing it ;)

Copy link
Member

@tlrx tlrx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, Thanks

@javanna javanna merged commit da669f0 into elastic:feature/client_aggs_parsing May 17, 2017
javanna added a commit to javanna/elasticsearch that referenced this pull request May 23, 2017
SearchResponse#fromXContent allows to parse a search response, including search hits, aggregations, suggestions and profile results. Only the aggs that we can parse today are supported (which means all of them but a couple that are left to support). SearchResponseTests reuses the existing test infra to randomize aggregations, suggestions and profile response.

Relates to elastic#23331
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants