-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Introduce SearchResponseSections base class #24442
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 |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| /* | ||
| * 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.action.search; | ||
|
|
||
| import org.elasticsearch.common.io.stream.StreamOutput; | ||
| import org.elasticsearch.common.xcontent.ToXContent; | ||
| import org.elasticsearch.common.xcontent.XContentBuilder; | ||
| import org.elasticsearch.search.SearchHits; | ||
| import org.elasticsearch.search.aggregations.Aggregations; | ||
| import org.elasticsearch.search.profile.ProfileShardResult; | ||
| import org.elasticsearch.search.profile.SearchProfileShardResults; | ||
| import org.elasticsearch.search.suggest.Suggest; | ||
|
|
||
| import java.io.IOException; | ||
| import java.util.Collections; | ||
| import java.util.Map; | ||
|
|
||
| /** | ||
| * Base class that holds the various sections which a search response is | ||
| * composed of (hits, aggs, suggestions etc.) and allows to retrieve them. | ||
| * | ||
| * The reason why this class exists is that the high level REST client uses its own classes | ||
| * to parse aggregations into, which are not serializable. This is the common part that can be | ||
| * shared between core and client. | ||
| */ | ||
| public class SearchResponseSections implements ToXContent { | ||
|
|
||
| protected final SearchHits hits; | ||
| protected final Aggregations aggregations; | ||
| protected final Suggest suggest; | ||
| protected final SearchProfileShardResults profileResults; | ||
| protected final boolean timedOut; | ||
| protected final Boolean terminatedEarly; | ||
| protected final int numReducePhases; | ||
|
|
||
| public SearchResponseSections(SearchHits hits, Aggregations aggregations, Suggest suggest, boolean timedOut, Boolean terminatedEarly, | ||
| SearchProfileShardResults profileResults, int numReducePhases) { | ||
| this.hits = hits; | ||
| this.aggregations = aggregations; | ||
| this.suggest = suggest; | ||
| this.profileResults = profileResults; | ||
| this.timedOut = timedOut; | ||
| this.terminatedEarly = terminatedEarly; | ||
| this.numReducePhases = numReducePhases; | ||
| } | ||
|
|
||
| public final boolean timedOut() { | ||
| return this.timedOut; | ||
| } | ||
|
|
||
| public final Boolean terminatedEarly() { | ||
| return this.terminatedEarly; | ||
| } | ||
|
|
||
| public final SearchHits hits() { | ||
| return hits; | ||
| } | ||
|
|
||
| public final Aggregations aggregations() { | ||
| return aggregations; | ||
| } | ||
|
|
||
| public final Suggest suggest() { | ||
| return suggest; | ||
| } | ||
|
|
||
| /** | ||
| * Returns the number of reduce phases applied to obtain this search response | ||
| */ | ||
| public final int getNumReducePhases() { | ||
| return numReducePhases; | ||
| } | ||
|
|
||
| /** | ||
| * Returns the profile results for this search response (including all shards). | ||
| * An empty map is returned if profiling was not enabled | ||
| * | ||
| * @return Profile results | ||
| */ | ||
| public final Map<String, ProfileShardResult> profile() { | ||
| if (profileResults == null) { | ||
| return Collections.emptyMap(); | ||
| } | ||
| return profileResults.getShardResults(); | ||
| } | ||
|
|
||
| @Override | ||
| public final XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { | ||
| hits.toXContent(builder, params); | ||
| if (aggregations != null) { | ||
| aggregations.toXContent(builder, params); | ||
| } | ||
| if (suggest != null) { | ||
| suggest.toXContent(builder, params); | ||
| } | ||
| if (profileResults != null) { | ||
| profileResults.toXContent(builder, params); | ||
| } | ||
| return builder; | ||
| } | ||
|
|
||
| protected void writeTo(StreamOutput out) throws IOException { | ||
| throw new UnsupportedOperationException(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,6 +18,13 @@ | |
| */ | ||
| package org.elasticsearch.search.aggregations; | ||
|
|
||
| import org.elasticsearch.common.xcontent.ToXContent; | ||
| import org.elasticsearch.common.xcontent.XContentBuilder; | ||
| import org.elasticsearch.common.xcontent.XContentParser; | ||
| import org.elasticsearch.common.xcontent.XContentParserUtils; | ||
|
|
||
| import java.io.IOException; | ||
| import java.util.ArrayList; | ||
| import java.util.Collections; | ||
| import java.util.HashMap; | ||
| import java.util.Iterator; | ||
|
|
@@ -30,7 +37,9 @@ | |
| /** | ||
| * Represents a set of {@link Aggregation}s | ||
| */ | ||
| public abstract class Aggregations implements Iterable<Aggregation> { | ||
| public class Aggregations implements Iterable<Aggregation>, ToXContent { | ||
|
|
||
| public static final String AGGREGATIONS_FIELD = "aggregations"; | ||
|
|
||
| protected List<? extends Aggregation> aggregations = Collections.emptyList(); | ||
| protected Map<String, Aggregation> aggregationsAsMap; | ||
|
|
@@ -98,4 +107,36 @@ public final boolean equals(Object obj) { | |
| public final int hashCode() { | ||
| return Objects.hash(getClass(), aggregations); | ||
| } | ||
|
|
||
| @Override | ||
| public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { | ||
| if (aggregations.isEmpty()) { | ||
|
||
| return builder; | ||
| } | ||
| builder.startObject(AGGREGATIONS_FIELD); | ||
| toXContentInternal(builder, params); | ||
| return builder.endObject(); | ||
| } | ||
|
|
||
| /** | ||
| * Directly write all the aggregations without their bounding object. Used by sub-aggregations (non top level aggs) | ||
| */ | ||
| public XContentBuilder toXContentInternal(XContentBuilder builder, Params params) throws IOException { | ||
| for (Aggregation aggregation : aggregations) { | ||
| aggregation.toXContent(builder, params); | ||
| } | ||
| return builder; | ||
| } | ||
|
|
||
| //TODO add tests for this method | ||
|
Member
Author
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. would you mind if I add tests as a follow-up so we can get this in rather quickly?
Member
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. ++ |
||
| public static Aggregations fromXContent(XContentParser parser) throws IOException { | ||
| final List<Aggregation> aggregations = new ArrayList<>(); | ||
| XContentParser.Token token; | ||
| while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { | ||
| if (token == XContentParser.Token.START_OBJECT) { | ||
| aggregations.add(XContentParserUtils.parseTypedKeysObject(parser, Aggregation.TYPED_KEYS_DELIMITER, Aggregation.class)); | ||
| } | ||
| } | ||
| return new Aggregations(aggregations); | ||
| } | ||
| } | ||
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.
What about
BaseSearchResponse? I find this sections suffix confusing, but maybe it's just me.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.
BaseSearchResponse makes me think that it has to do with its ancestor. I went for sections because it holds the different sections of the search response, in the same spirit as Aggregations.
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.
Ok