@Override
 public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
   builder.startObject();
   if (docBuilder != null) {
     docBuilder.toXContent(builder, params);
   }
   if (queryBuilder != null) {
     builder.field("query");
     queryBuilder.toXContent(builder, params);
   }
   if (size != null) {
     builder.field("size", size);
   }
   if (sorts != null) {
     builder.startArray("sort");
     for (SortBuilder<?> sort : sorts) {
       sort.toXContent(builder, params);
     }
     builder.endArray();
   }
   if (trackScores != null) {
     builder.field("track_scores", trackScores);
   }
   if (highlightBuilder != null) {
     builder.field(SearchSourceBuilder.HIGHLIGHT_FIELD.getPreferredName(), highlightBuilder);
   }
   if (aggregationBuilders != null || pipelineAggregationBuilders != null) {
     builder.field("aggregations");
     builder.startObject();
     if (aggregationBuilders != null) {
       for (AggregatorBuilder<?> aggregation : aggregationBuilders) {
         aggregation.toXContent(builder, params);
       }
     }
     if (pipelineAggregationBuilders != null) {
       for (PipelineAggregatorBuilder<?> aggregation : pipelineAggregationBuilders) {
         aggregation.toXContent(builder, params);
       }
     }
     builder.endObject();
   }
   builder.endObject();
   return builder;
 }
 /** Adds a sort builder. */
 public SearchSourceBuilder sort(SortBuilder sort) {
   try {
     if (sorts == null) {
       sorts = new ArrayList<>();
     }
     XContentBuilder builder = XContentFactory.jsonBuilder();
     builder.startObject();
     sort.toXContent(builder, EMPTY_PARAMS);
     builder.endObject();
     sorts.add(builder.bytes());
     return this;
   } catch (IOException e) {
     throw new RuntimeException(e);
   }
 }
  @Override
  public void toXContent(XContentBuilder builder, Params params) throws IOException {
    builder.startObject();

    if (from != -1) {
      builder.field("from", from);
    }
    if (size != -1) {
      builder.field("size", size);
    }
    if (queryParserName != null) {
      builder.field("query_parser_name", queryParserName);
    }

    if (queryBuilder != null) {
      builder.field("query");
      queryBuilder.toXContent(builder, params);
    }

    if (queryBinary != null) {
      if (XContentFactory.xContentType(queryBinary) == builder.contentType()) {
        builder.rawField("query", queryBinary);
      } else {
        builder.field("query_binary");
        builder.value(queryBinary);
      }
    }

    if (explain != null) {
      builder.field("explain", explain);
    }

    if (fieldNames != null) {
      if (fieldNames.size() == 1) {
        builder.field("fields", fieldNames.get(0));
      } else {
        builder.startArray("fields");
        for (String fieldName : fieldNames) {
          builder.value(fieldName);
        }
        builder.endArray();
      }
    }

    if (scriptFields != null) {
      builder.startObject("script_fields");
      for (ScriptField scriptField : scriptFields) {
        builder.startObject(scriptField.fieldName());
        builder.field("script", scriptField.script());
        if (scriptField.params() != null) {
          builder.field("params");
          builder.map(scriptField.params());
        }
        builder.endObject();
      }
      builder.endObject();
    }

    if (sorts != null) {
      builder.startArray("sort");
      for (SortBuilder sort : sorts) {
        builder.startObject();
        sort.toXContent(builder, params);
        builder.endObject();
      }
      builder.endArray();
    }

    if (indexBoost != null) {
      builder.startObject("indices_boost");
      for (TObjectFloatIterator<String> it = indexBoost.iterator(); it.hasNext(); ) {
        it.advance();
        builder.field(it.key(), it.value());
      }
      builder.endObject();
    }

    if (facets != null) {
      builder.field("facets");
      builder.startObject();
      for (AbstractFacetBuilder facet : facets) {
        facet.toXContent(builder, params);
      }
      builder.endObject();
    }

    if (highlightBuilder != null) {
      highlightBuilder.toXContent(builder, params);
    }

    builder.endObject();
  }
 @Override
 public Aggregator createInternal(
     Aggregator parent,
     boolean collectsFromSingleBucket,
     List<PipelineAggregator> pipelineAggregators,
     Map<String, Object> metaData)
     throws IOException {
   SubSearchContext subSearchContext = new SubSearchContext(context.searchContext());
   subSearchContext.parsedQuery(context.searchContext().parsedQuery());
   subSearchContext.explain(explain);
   subSearchContext.version(version);
   subSearchContext.trackScores(trackScores);
   subSearchContext.from(from);
   subSearchContext.size(size);
   if (sorts != null) {
     Optional<SortAndFormats> optionalSort =
         SortBuilder.buildSort(sorts, subSearchContext.getQueryShardContext());
     if (optionalSort.isPresent()) {
       subSearchContext.sort(optionalSort.get());
     }
   }
   if (fieldNames != null) {
     subSearchContext.fieldNames().addAll(fieldNames);
   }
   if (docValueFields != null) {
     DocValueFieldsContext docValueFieldsContext =
         subSearchContext.getFetchSubPhaseContext(DocValueFieldsFetchSubPhase.CONTEXT_FACTORY);
     for (String field : docValueFields) {
       docValueFieldsContext.add(new DocValueField(field));
     }
     docValueFieldsContext.setHitExecutionNeeded(true);
   }
   if (scriptFields != null) {
     for (ScriptField field : scriptFields) {
       SearchScript searchScript =
           subSearchContext
               .scriptService()
               .search(
                   subSearchContext.lookup(),
                   field.script(),
                   ScriptContext.Standard.SEARCH,
                   Collections.emptyMap());
       subSearchContext
           .scriptFields()
           .add(
               new org.elasticsearch.search.fetch.script.ScriptFieldsContext.ScriptField(
                   field.fieldName(), searchScript, field.ignoreFailure()));
     }
   }
   if (fetchSourceContext != null) {
     subSearchContext.fetchSourceContext(fetchSourceContext);
   }
   if (highlightBuilder != null) {
     subSearchContext.highlight(
         highlightBuilder.build(context.searchContext().getQueryShardContext()));
   }
   return new TopHitsAggregator(
       context.searchContext().fetchPhase(),
       subSearchContext,
       name,
       context,
       parent,
       pipelineAggregators,
       metaData);
 }