Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,13 @@
import java.util.Map;

import static org.elasticsearch.action.search.ShardSearchFailure.readShardSearchFailure;
import static org.elasticsearch.search.internal.InternalSearchResponse.readInternalSearchResponse;

/**
* A response of a search request.
*/
public class SearchResponse extends ActionResponse implements StatusToXContentObject {

private InternalSearchResponse internalResponse;
private SearchResponseSections internalResponse;
Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member

Choose a reason for hiding this comment

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

Ok


private String scrollId;

Expand All @@ -61,7 +60,7 @@ public class SearchResponse extends ActionResponse implements StatusToXContentOb
public SearchResponse() {
}

public SearchResponse(InternalSearchResponse internalResponse, String scrollId, int totalShards, int successfulShards,
public SearchResponse(SearchResponseSections internalResponse, String scrollId, int totalShards, int successfulShards,
long tookInMillis, ShardSearchFailure[] shardFailures) {
this.internalResponse = internalResponse;
this.scrollId = scrollId;
Expand Down Expand Up @@ -209,7 +208,7 @@ public XContentBuilder innerToXContent(XContentBuilder builder, Params params) t
@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
internalResponse = readInternalSearchResponse(in);
internalResponse = new InternalSearchResponse(in);
totalShards = in.readVInt();
successfulShards = in.readVInt();
int size = in.readVInt();
Expand Down
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
Expand Up @@ -19,13 +19,14 @@
package org.elasticsearch.search.aggregations;

import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.xcontent.ToXContent;

import java.util.Map;

/**
* An aggregation
* An aggregation. Extends {@link ToXContent} as it makes it easier to print out its content.
*/
public interface Aggregation {
public interface Aggregation extends ToXContent {

/**
* Delimiter used when prefixing aggregation names with their type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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()) {
Copy link
Member

Choose a reason for hiding this comment

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

aggregations is not initialized with emptyList() anymore, I think this might cause an issue here

Copy link
Member Author

Choose a reason for hiding this comment

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

yea I forgot to push a commit. I had already fixed this, good catch.

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
Copy link
Member Author

Choose a reason for hiding this comment

The 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?

Copy link
Member

Choose a reason for hiding this comment

The 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Streamable;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.search.aggregations.InternalAggregation.ReduceContext;

import java.io.IOException;
Expand All @@ -32,6 +31,7 @@
import java.util.Map;

import static java.util.Collections.emptyMap;

/**
* An internal implementation of {@link Aggregations}.
*/
Expand Down Expand Up @@ -80,27 +80,6 @@ public static InternalAggregations reduce(List<InternalAggregations> aggregation
return new InternalAggregations(reducedAggregations);
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
if (aggregations.isEmpty()) {
return builder;
}
builder.startObject("aggregations");
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) {
((InternalAggregation)aggregation).toXContent(builder, params);
}
return builder;
}


public static InternalAggregations readAggregations(StreamInput in) throws IOException {
InternalAggregations result = new InternalAggregations();
result.readFrom(in);
Expand Down
Loading