Browse Source

Rename `fields` to `stored_fields` and add `docvalue_fields`

`stored_fields` parameter will no longer try to retrieve fields from the _source but will only return stored fields.
`fields` will throw an exception if the user uses it.
Add `docvalue_fields` as an adjunct to `fielddata_fields` which is deprecated. `docvalue_fields` will try to load the value from the docvalue and fallback to fielddata cache if docvalues are not enabled on that field.

Closes #18943
Jim Ferenczi 9 years ago
parent
commit
2f46f53dc8
45 changed files with 447 additions and 312 deletions
  1. 33 8
      core/src/main/java/org/elasticsearch/action/search/SearchRequestBuilder.java
  2. 154 74
      core/src/main/java/org/elasticsearch/index/query/InnerHitBuilder.java
  3. 20 11
      core/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java
  4. 4 4
      core/src/main/java/org/elasticsearch/search/SearchService.java
  5. 6 6
      core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/TopHitsAggregationBuilder.java
  6. 85 77
      core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java
  7. 1 1
      core/src/test/java/org/elasticsearch/index/IndexWithShadowReplicasIT.java
  8. 2 2
      core/src/test/java/org/elasticsearch/index/mapper/core/TokenCountFieldMapperIntegrationIT.java
  9. 4 4
      core/src/test/java/org/elasticsearch/index/mapper/geo/GeoPointFieldMapperTests.java
  10. 7 7
      core/src/test/java/org/elasticsearch/index/query/InnerHitBuilderTests.java
  11. 1 1
      core/src/test/java/org/elasticsearch/index/store/ExceptionRetryIT.java
  12. 2 2
      core/src/test/java/org/elasticsearch/indices/template/SimpleIndexTemplateIT.java
  13. 1 1
      core/src/test/java/org/elasticsearch/recovery/RelocationIT.java
  14. 1 1
      core/src/test/java/org/elasticsearch/search/aggregations/metrics/AbstractGeoTestCase.java
  15. 2 2
      core/src/test/java/org/elasticsearch/search/builder/SearchSourceBuilderTests.java
  16. 4 4
      core/src/test/java/org/elasticsearch/search/child/ChildQuerySearchIT.java
  17. 2 2
      core/src/test/java/org/elasticsearch/search/geo/GeoFilterIT.java
  18. 2 2
      core/src/test/java/org/elasticsearch/search/innerhits/InnerHitsIT.java
  19. 2 2
      core/src/test/java/org/elasticsearch/search/source/SourceFetchingIT.java
  20. 1 1
      core/src/test/java/org/elasticsearch/update/TimestampTTLBWIT.java
  21. 2 2
      docs/plugins/mapper-attachments.asciidoc
  22. 1 1
      docs/reference/aggregations/metrics/tophits-aggregation.asciidoc
  23. 1 1
      docs/reference/mapping/params/store.asciidoc
  24. 7 3
      docs/reference/migration/migrate_5_0/search.asciidoc
  25. 1 1
      docs/reference/modules/scripting/painless.asciidoc
  26. 2 2
      docs/reference/search/request-body.asciidoc
  27. 23 0
      docs/reference/search/request/docvalue-fields.asciidoc
  28. 0 23
      docs/reference/search/request/fielddata-fields.asciidoc
  29. 1 1
      docs/reference/search/request/highlighting.asciidoc
  30. 1 1
      docs/reference/search/request/inner-hits.asciidoc
  31. 3 3
      docs/reference/search/request/stored-fields.asciidoc
  32. 1 1
      docs/reference/search/uri-request.asciidoc
  33. 8 8
      modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/GeoDistanceTests.java
  34. 33 33
      modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SearchFieldsTests.java
  35. 2 2
      modules/reindex/src/main/java/org/elasticsearch/index/reindex/AbstractBulkByScrollRequest.java
  36. 2 2
      modules/reindex/src/test/resources/rest-api-spec/test/delete_by_query/20_validation.yaml
  37. 2 2
      modules/reindex/src/test/resources/rest-api-spec/test/reindex/20_validation.yaml
  38. 2 2
      modules/reindex/src/test/resources/rest-api-spec/test/update_by_query/20_validation.yaml
  39. 1 1
      plugins/mapper-attachments/src/test/resources/rest-api-spec/test/mapper_attachments/30_mapping.yaml
  40. 1 1
      plugins/mapper-attachments/src/test/resources/rest-api-spec/test/mapper_attachments/40_highlight.yaml
  41. 2 2
      plugins/mapper-attachments/src/test/resources/rest-api-spec/test/mapper_attachments/50_files_supported.yaml
  42. 2 2
      plugins/mapper-size/src/test/java/org/elasticsearch/index/mapper/size/SizeFieldMapperUpgradeTests.java
  43. 7 3
      rest-api-spec/src/main/resources/rest-api-spec/api/search.json
  44. 7 2
      rest-api-spec/src/main/resources/rest-api-spec/test/search/10_source_filtering.yaml
  45. 1 1
      rest-api-spec/src/main/resources/rest-api-spec/test/search/issue4895.yaml

+ 33 - 8
core/src/main/java/org/elasticsearch/action/search/SearchRequestBuilder.java

@@ -253,8 +253,8 @@ public class SearchRequestBuilder extends ActionRequestBuilder<SearchRequest, Se
     /**
      * Sets no fields to be loaded, resulting in only id and type to be returned per field.
      */
-    public SearchRequestBuilder setNoFields() {
-        sourceBuilder().noFields();
+    public SearchRequestBuilder setNoStoredFields() {
+        sourceBuilder().noStoredFields();
         return this;
     }
 
@@ -290,13 +290,23 @@ public class SearchRequestBuilder extends ActionRequestBuilder<SearchRequest, Se
         return this;
     }
 
+    /**
+     * Adds a docvalue based field to load and return. The field does not have to be stored,
+     * but its recommended to use non analyzed or numeric fields.
+     *
+     * @param name The field to get from the docvalue
+     */
+    public SearchRequestBuilder addDocValueField(String name) {
+        sourceBuilder().docValueField(name);
+        return this;
+    }
 
     /**
-     * Adds a field to load and return (note, it must be stored) as part of the search request.
+     * Adds a stored field to load and return (note, it must be stored) as part of the search request.
      * If none are specified, the source of the document will be return.
      */
-    public SearchRequestBuilder addField(String field) {
-        sourceBuilder().field(field);
+    public SearchRequestBuilder addStoredField(String field) {
+        sourceBuilder().storedField(field);
         return this;
     }
 
@@ -305,12 +315,15 @@ public class SearchRequestBuilder extends ActionRequestBuilder<SearchRequest, Se
      * but its recommended to use non analyzed or numeric fields.
      *
      * @param name The field to get from the field data cache
+     * @deprecated Use {@link SearchRequestBuilder#addDocValueField(String)} instead.
      */
+    @Deprecated
     public SearchRequestBuilder addFieldDataField(String name) {
-        sourceBuilder().fieldDataField(name);
+        sourceBuilder().docValueField(name);
         return this;
     }
 
+
     /**
      * Adds a script based field to load and return. The field does not have to be stored,
      * but its recommended to use non analyzed or numeric fields.
@@ -368,11 +381,23 @@ public class SearchRequestBuilder extends ActionRequestBuilder<SearchRequest, Se
     }
 
     /**
-     * Sets the fields to load and return as part of the search request. If none
+     * Sets the stored fields to load and return as part of the search request. If none
      * are specified, the source of the document will be returned.
+     *
+     * @deprecated Use {@link SearchRequestBuilder#storedFields(String...)} instead.
      */
+    @Deprecated
     public SearchRequestBuilder fields(String... fields) {
-        sourceBuilder().fields(Arrays.asList(fields));
+        sourceBuilder().storedFields(Arrays.asList(fields));
+        return this;
+    }
+
+    /**
+     * Sets the fields to load and return as part of the search request. If none
+     * are specified, the source of the document will be returned.
+     */
+    public SearchRequestBuilder storedFields(String... fields) {
+        sourceBuilder().storedFields(Arrays.asList(fields));
         return this;
     }
 

+ 154 - 74
core/src/main/java/org/elasticsearch/index/query/InnerHitBuilder.java

@@ -71,8 +71,14 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl
         PARSER.declareBoolean(InnerHitBuilder::setExplain, SearchSourceBuilder.EXPLAIN_FIELD);
         PARSER.declareBoolean(InnerHitBuilder::setVersion, SearchSourceBuilder.VERSION_FIELD);
         PARSER.declareBoolean(InnerHitBuilder::setTrackScores, SearchSourceBuilder.TRACK_SCORES_FIELD);
-        PARSER.declareStringArray(InnerHitBuilder::setFieldNames, SearchSourceBuilder.FIELDS_FIELD);
-        PARSER.declareStringArray(InnerHitBuilder::setFieldDataFields, SearchSourceBuilder.FIELDDATA_FIELDS_FIELD);
+        PARSER.declareStringArray(InnerHitBuilder::setStoredFieldNames, SearchSourceBuilder.STORED_FIELDS_FIELD);
+        PARSER.declareField((p, i, c) -> {
+            throw new ParsingException(p.getTokenLocation(), "The field [" +
+                SearchSourceBuilder.FIELDS_FIELD + "] is not longer supported, please use [" +
+                SearchSourceBuilder.STORED_FIELDS_FIELD + "] to retrieve stored fields or _source filtering " +
+                "if the field is not stored");
+        }, SearchSourceBuilder.FIELDS_FIELD, ObjectParser.ValueType.STRING_ARRAY);
+        PARSER.declareStringArray(InnerHitBuilder::setDocValueFields, SearchSourceBuilder.DOCVALUE_FIELDS_FIELD);
         PARSER.declareField((p, i, c) -> {
             try {
                 Set<ScriptField> scriptFields = new HashSet<>();
@@ -131,10 +137,10 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl
     private boolean version;
     private boolean trackScores;
 
-    private List<String> fieldNames;
+    private List<String> storedFieldNames;
     private QueryBuilder query = DEFAULT_INNER_HIT_QUERY;
     private List<SortBuilder<?>> sorts;
-    private List<String> fieldDataFields;
+    private List<String> docValueFields;
     private Set<ScriptField> scriptFields;
     private HighlightBuilder highlightBuilder;
     private FetchSourceContext fetchSourceContext;
@@ -143,46 +149,6 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl
     public InnerHitBuilder() {
     }
 
-    /**
-     * Read from a stream.
-     */
-    public InnerHitBuilder(StreamInput in) throws IOException {
-        name = in.readOptionalString();
-        nestedPath = in.readOptionalString();
-        parentChildType = in.readOptionalString();
-        from = in.readVInt();
-        size = in.readVInt();
-        explain = in.readBoolean();
-        version = in.readBoolean();
-        trackScores = in.readBoolean();
-        fieldNames = (List<String>) in.readGenericValue();
-        fieldDataFields = (List<String>) in.readGenericValue();
-        if (in.readBoolean()) {
-            int size = in.readVInt();
-            scriptFields = new HashSet<>(size);
-            for (int i = 0; i < size; i++) {
-                scriptFields.add(new ScriptField(in));
-            }
-        }
-        fetchSourceContext = in.readOptionalStreamable(FetchSourceContext::new);
-        if (in.readBoolean()) {
-            int size = in.readVInt();
-            sorts = new ArrayList<>(size);
-            for (int i = 0; i < size; i++) {
-                sorts.add(in.readNamedWriteable(SortBuilder.class));
-            }
-        }
-        highlightBuilder = in.readOptionalWriteable(HighlightBuilder::new);
-        query = in.readNamedWriteable(QueryBuilder.class);
-        if (in.readBoolean()) {
-            int size = in.readVInt();
-            childInnerHits = new HashMap<>(size);
-            for (int i = 0; i < size; i++) {
-                childInnerHits.put(in.readString(), new InnerHitBuilder(in));
-            }
-        }
-    }
-
     private InnerHitBuilder(InnerHitBuilder other) {
         name = other.name;
         from = other.from;
@@ -190,11 +156,11 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl
         explain = other.explain;
         version = other.version;
         trackScores = other.trackScores;
-        if (other.fieldNames != null) {
-            fieldNames = new ArrayList<>(other.fieldNames);
+        if (other.storedFieldNames != null) {
+            storedFieldNames = new ArrayList<>(other.storedFieldNames);
         }
-        if (other.fieldDataFields != null) {
-            fieldDataFields = new ArrayList<>(other.fieldDataFields);
+        if (other.docValueFields != null) {
+            docValueFields = new ArrayList<>(other.docValueFields);
         }
         if (other.scriptFields != null) {
             scriptFields = new HashSet<>(other.scriptFields);
@@ -232,6 +198,46 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl
         }
     }
 
+    /**
+     * Read from a stream.
+     */
+    public InnerHitBuilder(StreamInput in) throws IOException {
+        name = in.readOptionalString();
+        nestedPath = in.readOptionalString();
+        parentChildType = in.readOptionalString();
+        from = in.readVInt();
+        size = in.readVInt();
+        explain = in.readBoolean();
+        version = in.readBoolean();
+        trackScores = in.readBoolean();
+        storedFieldNames = (List<String>) in.readGenericValue();
+        docValueFields = (List<String>) in.readGenericValue();
+        if (in.readBoolean()) {
+            int size = in.readVInt();
+            scriptFields = new HashSet<>(size);
+            for (int i = 0; i < size; i++) {
+                scriptFields.add(new ScriptField(in));
+            }
+        }
+        fetchSourceContext = in.readOptionalStreamable(FetchSourceContext::new);
+        if (in.readBoolean()) {
+            int size = in.readVInt();
+            sorts = new ArrayList<>(size);
+            for (int i = 0; i < size; i++) {
+                sorts.add(in.readNamedWriteable(SortBuilder.class));
+            }
+        }
+        highlightBuilder = in.readOptionalWriteable(HighlightBuilder::new);
+        query = in.readNamedWriteable(QueryBuilder.class);
+        if (in.readBoolean()) {
+            int size = in.readVInt();
+            childInnerHits = new HashMap<>(size);
+            for (int i = 0; i < size; i++) {
+                childInnerHits.put(in.readString(), new InnerHitBuilder(in));
+            }
+        }
+    }
+
     @Override
     public void writeTo(StreamOutput out) throws IOException {
         out.writeOptionalString(name);
@@ -242,8 +248,8 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl
         out.writeBoolean(explain);
         out.writeBoolean(version);
         out.writeBoolean(trackScores);
-        out.writeGenericValue(fieldNames);
-        out.writeGenericValue(fieldDataFields);
+        out.writeGenericValue(storedFieldNames);
+        out.writeGenericValue(docValueFields);
         boolean hasScriptFields = scriptFields != null;
         out.writeBoolean(hasScriptFields);
         if (hasScriptFields) {
@@ -334,29 +340,103 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl
         return this;
     }
 
+    /**
+     * Gets the stored fields to load and return.
+     *
+     * @deprecated Use {@link InnerHitBuilder#getStoredFieldNames()} instead.
+     */
+    @Deprecated
     public List<String> getFieldNames() {
-        return fieldNames;
+        return storedFieldNames;
     }
 
+    /**
+     * Sets the stored fields to load and return. If none
+     * are specified, the source of the document will be returned.
+     *
+     * @deprecated Use {@link InnerHitBuilder#setStoredFieldNames(List)} instead.
+     */
+    @Deprecated
     public InnerHitBuilder setFieldNames(List<String> fieldNames) {
-        this.fieldNames = fieldNames;
+        this.storedFieldNames = fieldNames;
+        return this;
+    }
+
+
+    /**
+     * Gets the stored fields to load and return.
+     */
+    public List<String> getStoredFieldNames() {
+        return storedFieldNames;
+    }
+
+    /**
+     * Sets the stored fields to load and return. If none
+     * are specified, the source of the document will be returned.
+     */
+    public InnerHitBuilder setStoredFieldNames(List<String> fieldNames) {
+        this.storedFieldNames = fieldNames;
         return this;
     }
 
+    /**
+     * Gets the docvalue fields.
+     *
+     * @deprecated Use {@link InnerHitBuilder#getDocValueFields()} instead.
+     */
+    @Deprecated
     public List<String> getFieldDataFields() {
-        return fieldDataFields;
+        return docValueFields;
     }
 
+    /**
+     * Sets the stored fields to load from the docvalue and return.
+     *
+     * @deprecated Use {@link InnerHitBuilder#setDocValueFields(List)} instead.
+     */
+    @Deprecated
     public InnerHitBuilder setFieldDataFields(List<String> fieldDataFields) {
-        this.fieldDataFields = fieldDataFields;
+        this.docValueFields = fieldDataFields;
         return this;
     }
 
+    /**
+     * Adds a field to load from the docvalue and return.
+     *
+     * @deprecated Use {@link InnerHitBuilder#addDocValueField(String)} instead.
+     */
+    @Deprecated
     public InnerHitBuilder addFieldDataField(String field) {
-        if (fieldDataFields == null) {
-            fieldDataFields = new ArrayList<>();
+        if (docValueFields == null) {
+            docValueFields = new ArrayList<>();
+        }
+        docValueFields.add(field);
+        return this;
+    }
+
+    /**
+     * Gets the docvalue fields.
+     */
+    public List<String> getDocValueFields() {
+        return docValueFields;
+    }
+
+    /**
+     * Sets the stored fields to load from the docvalue and return.
+     */
+    public InnerHitBuilder setDocValueFields(List<String> docValueFields) {
+        this.docValueFields = docValueFields;
+        return this;
+    }
+
+    /**
+     * Adds a field to load from the docvalue and return.
+     */
+    public InnerHitBuilder addDocValueField(String field) {
+        if (docValueFields == null) {
+            docValueFields = new ArrayList<>();
         }
-        fieldDataFields.add(field);
+        docValueFields.add(field);
         return this;
     }
 
@@ -484,19 +564,19 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl
         innerHitsContext.explain(explain);
         innerHitsContext.version(version);
         innerHitsContext.trackScores(trackScores);
-        if (fieldNames != null) {
-            if (fieldNames.isEmpty()) {
+        if (storedFieldNames != null) {
+            if (storedFieldNames.isEmpty()) {
                 innerHitsContext.emptyFieldNames();
             } else {
-                for (String fieldName : fieldNames) {
+                for (String fieldName : storedFieldNames) {
                     innerHitsContext.fieldNames().add(fieldName);
                 }
             }
         }
-        if (fieldDataFields != null) {
+        if (docValueFields != null) {
             FieldDataFieldsContext fieldDataFieldsContext = innerHitsContext
                     .getFetchSubPhaseContext(FieldDataFieldsFetchSubPhase.CONTEXT_FACTORY);
-            for (String field : fieldDataFields) {
+            for (String field : docValueFields) {
                 fieldDataFieldsContext.add(new FieldDataFieldsContext.FieldDataField(field));
             }
             fieldDataFieldsContext.setHitExecutionNeeded(true);
@@ -553,20 +633,20 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl
         if (fetchSourceContext != null) {
             builder.field(SearchSourceBuilder._SOURCE_FIELD.getPreferredName(), fetchSourceContext, params);
         }
-        if (fieldNames != null) {
-            if (fieldNames.size() == 1) {
-                builder.field(SearchSourceBuilder.FIELDS_FIELD.getPreferredName(), fieldNames.get(0));
+        if (storedFieldNames != null) {
+            if (storedFieldNames.size() == 1) {
+                builder.field(SearchSourceBuilder.STORED_FIELDS_FIELD.getPreferredName(), storedFieldNames.get(0));
             } else {
-                builder.startArray(SearchSourceBuilder.FIELDS_FIELD.getPreferredName());
-                for (String fieldName : fieldNames) {
+                builder.startArray(SearchSourceBuilder.STORED_FIELDS_FIELD.getPreferredName());
+                for (String fieldName : storedFieldNames) {
                     builder.value(fieldName);
                 }
                 builder.endArray();
             }
         }
-        if (fieldDataFields != null) {
-            builder.startArray(SearchSourceBuilder.FIELDDATA_FIELDS_FIELD.getPreferredName());
-            for (String fieldDataField : fieldDataFields) {
+        if (docValueFields != null) {
+            builder.startArray(SearchSourceBuilder.DOCVALUE_FIELDS_FIELD.getPreferredName());
+            for (String fieldDataField : docValueFields) {
                 builder.value(fieldDataField);
             }
             builder.endArray();
@@ -613,8 +693,8 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl
                 Objects.equals(explain, that.explain) &&
                 Objects.equals(version, that.version) &&
                 Objects.equals(trackScores, that.trackScores) &&
-                Objects.equals(fieldNames, that.fieldNames) &&
-                Objects.equals(fieldDataFields, that.fieldDataFields) &&
+                Objects.equals(storedFieldNames, that.storedFieldNames) &&
+                Objects.equals(docValueFields, that.docValueFields) &&
                 Objects.equals(scriptFields, that.scriptFields) &&
                 Objects.equals(fetchSourceContext, that.fetchSourceContext) &&
                 Objects.equals(sorts, that.sorts) &&
@@ -625,8 +705,8 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl
 
     @Override
     public int hashCode() {
-        return Objects.hash(name, nestedPath, parentChildType, from, size, explain, version, trackScores, fieldNames,
-                fieldDataFields, scriptFields, fetchSourceContext, sorts, highlightBuilder, query, childInnerHits);
+        return Objects.hash(name, nestedPath, parentChildType, from, size, explain, version, trackScores, storedFieldNames,
+            docValueFields, scriptFields, fetchSourceContext, sorts, highlightBuilder, query, childInnerHits);
     }
 
     public static InnerHitBuilder fromXContent(QueryParseContext context) throws IOException {

+ 20 - 11
core/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java

@@ -24,6 +24,7 @@ import org.elasticsearch.action.search.SearchType;
 import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.ParseFieldMatcher;
+import org.elasticsearch.common.ParsingException;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.bytes.BytesReference;
 import org.elasticsearch.common.inject.Inject;
@@ -195,27 +196,35 @@ public class RestSearchAction extends BaseRestHandler {
             }
         }
 
-        String sField = request.param("fields");
+        if (request.param("fields") != null) {
+            throw new IllegalArgumentException("The parameter [" +
+                SearchSourceBuilder.FIELDS_FIELD + "] is not longer supported, please use [" +
+                SearchSourceBuilder.STORED_FIELDS_FIELD + "] to retrieve stored fields or _source filtering " +
+                "if the field is not stored");
+        }
+
+        String sField = request.param("stored_fields");
         if (sField != null) {
             if (!Strings.hasText(sField)) {
-                searchSourceBuilder.noFields();
+                searchSourceBuilder.noStoredFields();
             } else {
                 String[] sFields = Strings.splitStringByCommaToArray(sField);
                 if (sFields != null) {
                     for (String field : sFields) {
-                        searchSourceBuilder.field(field);
+                        searchSourceBuilder.storedField(field);
                     }
                 }
             }
         }
-        String sFieldDataFields = request.param("fielddata_fields");
-        if (sFieldDataFields != null) {
-            if (Strings.hasText(sFieldDataFields)) {
-                String[] sFields = Strings.splitStringByCommaToArray(sFieldDataFields);
-                if (sFields != null) {
-                    for (String field : sFields) {
-                        searchSourceBuilder.fieldDataField(field);
-                    }
+        String sDocValueFields = request.param("docvalue_fields");
+        if (sDocValueFields == null) {
+            sDocValueFields = request.param("fielddata_fields");
+        }
+        if (sDocValueFields != null) {
+            if (Strings.hasText(sDocValueFields)) {
+                String[] sFields = Strings.splitStringByCommaToArray(sDocValueFields);
+                for (String field : sFields) {
+                    searchSourceBuilder.docValueField(field);
                 }
             }
         }

+ 4 - 4
core/src/main/java/org/elasticsearch/search/SearchService.java

@@ -733,8 +733,8 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> imp
                 throw new SearchContextException(context, "failed to create RescoreSearchContext", e);
             }
         }
-        if (source.fields() != null) {
-            context.fieldNames().addAll(source.fields());
+        if (source.storedFields() != null) {
+            context.fieldNames().addAll(source.storedFields());
         }
         if (source.explain() != null) {
             context.explain(source.explain());
@@ -742,9 +742,9 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> imp
         if (source.fetchSource() != null) {
             context.fetchSourceContext(source.fetchSource());
         }
-        if (source.fieldDataFields() != null) {
+        if (source.docValueFields() != null) {
             FieldDataFieldsContext fieldDataFieldsContext = context.getFetchSubPhaseContext(FieldDataFieldsFetchSubPhase.CONTEXT_FACTORY);
-            for (String field : source.fieldDataFields()) {
+            for (String field : source.docValueFields()) {
                 fieldDataFieldsContext.add(new FieldDataField(field));
             }
             fieldDataFieldsContext.setHitExecutionNeeded(true);

+ 6 - 6
core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/TopHitsAggregationBuilder.java

@@ -567,9 +567,9 @@ public class TopHitsAggregationBuilder extends AbstractAggregationBuilder<TopHit
         }
         if (fieldNames != null) {
             if (fieldNames.size() == 1) {
-                builder.field(SearchSourceBuilder.FIELDS_FIELD.getPreferredName(), fieldNames.get(0));
+                builder.field(SearchSourceBuilder.STORED_FIELDS_FIELD.getPreferredName(), fieldNames.get(0));
             } else {
-                builder.startArray(SearchSourceBuilder.FIELDS_FIELD.getPreferredName());
+                builder.startArray(SearchSourceBuilder.STORED_FIELDS_FIELD.getPreferredName());
                 for (String fieldName : fieldNames) {
                     builder.value(fieldName);
                 }
@@ -577,7 +577,7 @@ public class TopHitsAggregationBuilder extends AbstractAggregationBuilder<TopHit
             }
         }
         if (fieldDataFields != null) {
-            builder.startArray(SearchSourceBuilder.FIELDDATA_FIELDS_FIELD.getPreferredName());
+            builder.startArray(SearchSourceBuilder.DOCVALUE_FIELDS_FIELD.getPreferredName());
             for (String fieldDataField : fieldDataFields) {
                 builder.value(fieldDataField);
             }
@@ -628,7 +628,7 @@ public class TopHitsAggregationBuilder extends AbstractAggregationBuilder<TopHit
                     factory.trackScores(parser.booleanValue());
                 } else if (context.getParseFieldMatcher().match(currentFieldName, SearchSourceBuilder._SOURCE_FIELD)) {
                     factory.fetchSource(FetchSourceContext.parse(context));
-                } else if (context.getParseFieldMatcher().match(currentFieldName, SearchSourceBuilder.FIELDS_FIELD)) {
+                } else if (context.getParseFieldMatcher().match(currentFieldName, SearchSourceBuilder.STORED_FIELDS_FIELD)) {
                     List<String> fieldNames = new ArrayList<>();
                     fieldNames.add(parser.text());
                     factory.fields(fieldNames);
@@ -694,7 +694,7 @@ public class TopHitsAggregationBuilder extends AbstractAggregationBuilder<TopHit
                 }
             } else if (token == XContentParser.Token.START_ARRAY) {
 
-                if (context.getParseFieldMatcher().match(currentFieldName, SearchSourceBuilder.FIELDS_FIELD)) {
+                if (context.getParseFieldMatcher().match(currentFieldName, SearchSourceBuilder.STORED_FIELDS_FIELD)) {
                     List<String> fieldNames = new ArrayList<>();
                     while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
                         if (token == XContentParser.Token.VALUE_STRING) {
@@ -705,7 +705,7 @@ public class TopHitsAggregationBuilder extends AbstractAggregationBuilder<TopHit
                         }
                     }
                     factory.fields(fieldNames);
-                } else if (context.getParseFieldMatcher().match(currentFieldName, SearchSourceBuilder.FIELDDATA_FIELDS_FIELD)) {
+                } else if (context.getParseFieldMatcher().match(currentFieldName, SearchSourceBuilder.DOCVALUE_FIELDS_FIELD)) {
                     List<String> fieldDataFields = new ArrayList<>();
                     while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
                         if (token == XContentParser.Token.VALUE_STRING) {

+ 85 - 77
core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java

@@ -84,7 +84,8 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
     public static final ParseField EXPLAIN_FIELD = new ParseField("explain");
     public static final ParseField _SOURCE_FIELD = new ParseField("_source");
     public static final ParseField FIELDS_FIELD = new ParseField("fields");
-    public static final ParseField FIELDDATA_FIELDS_FIELD = new ParseField("fielddata_fields");
+    public static final ParseField STORED_FIELDS_FIELD = new ParseField("stored_fields");
+    public static final ParseField DOCVALUE_FIELDS_FIELD = new ParseField("docvalue_fields", "fielddata_fields");
     public static final ParseField SCRIPT_FIELDS_FIELD = new ParseField("script_fields");
     public static final ParseField SCRIPT_FIELD = new ParseField("script");
     public static final ParseField IGNORE_FAILURE_FIELD = new ParseField("ignore_failure");
@@ -147,8 +148,8 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
     private long timeoutInMillis = -1;
     private int terminateAfter = SearchContext.DEFAULT_TERMINATE_AFTER;
 
-    private List<String> fieldNames;
-    private List<String> fieldDataFields;
+    private List<String> storedFieldNames;
+    private List<String> docValueFields;
     private List<ScriptField> scriptFields;
     private FetchSourceContext fetchSourceContext;
 
@@ -182,22 +183,8 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
         aggregations = in.readOptionalWriteable(AggregatorFactories.Builder::new);
         explain = in.readOptionalBoolean();
         fetchSourceContext = in.readOptionalStreamable(FetchSourceContext::new);
-        boolean hasFieldDataFields = in.readBoolean();
-        if (hasFieldDataFields) {
-            int size = in.readVInt();
-            fieldDataFields = new ArrayList<>(size);
-            for (int i = 0; i < size; i++) {
-                fieldDataFields.add(in.readString());
-            }
-        }
-        boolean hasFieldNames = in.readBoolean();
-        if (hasFieldNames) {
-            int size = in.readVInt();
-            fieldNames = new ArrayList<>(size);
-            for (int i = 0; i < size; i++) {
-                fieldNames.add(in.readString());
-            }
-        }
+        docValueFields = (List<String>) in.readGenericValue();
+        storedFieldNames = (List<String>) in.readGenericValue();
         from = in.readVInt();
         highlightBuilder = in.readOptionalWriteable(HighlightBuilder::new);
         boolean hasIndexBoost = in.readBoolean();
@@ -256,22 +243,8 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
         out.writeOptionalWriteable(aggregations);
         out.writeOptionalBoolean(explain);
         out.writeOptionalStreamable(fetchSourceContext);
-        boolean hasFieldDataFields = fieldDataFields != null;
-        out.writeBoolean(hasFieldDataFields);
-        if (hasFieldDataFields) {
-            out.writeVInt(fieldDataFields.size());
-            for (String field : fieldDataFields) {
-                out.writeString(field);
-            }
-        }
-        boolean hasFieldNames = fieldNames != null;
-        out.writeBoolean(hasFieldNames);
-        if (hasFieldNames) {
-            out.writeVInt(fieldNames.size());
-            for (String field : fieldNames) {
-                out.writeString(field);
-            }
-        }
+        out.writeGenericValue(docValueFields);
+        out.writeGenericValue(storedFieldNames);
         out.writeVInt(from);
         out.writeOptionalWriteable(highlightBuilder);
         boolean hasIndexBoost = indexBoost != null;
@@ -733,60 +706,87 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
     }
 
     /**
-     * Adds a field to load and return (note, it must be stored) as part of the
+     * Adds a stored field to load and return as part of the
      * search request. If none are specified, the source of the document will be
      * return.
      */
-    public SearchSourceBuilder field(String name) {
-        if (fieldNames == null) {
-            fieldNames = new ArrayList<>();
+    public SearchSourceBuilder storedField(String name) {
+        if (storedFieldNames == null) {
+            storedFieldNames = new ArrayList<>();
         }
-        fieldNames.add(name);
+        storedFieldNames.add(name);
         return this;
     }
 
     /**
-     * Sets the fields to load and return as part of the search request. If none
+     * Sets the stored fields to load and return as part of the search request. If none
      * are specified, the source of the document will be returned.
      */
-    public SearchSourceBuilder fields(List<String> fields) {
-        this.fieldNames = fields;
+    public SearchSourceBuilder storedFields(List<String> fields) {
+        this.storedFieldNames = fields;
         return this;
     }
 
     /**
-     * Sets no fields to be loaded, resulting in only id and type to be returned
+     * Sets no stored fields to be loaded, resulting in only id and type to be returned
      * per field.
      */
-    public SearchSourceBuilder noFields() {
-        this.fieldNames = Collections.emptyList();
+    public SearchSourceBuilder noStoredFields() {
+        this.storedFieldNames = Collections.emptyList();
         return this;
     }
 
     /**
-     * Gets the fields to load and return as part of the search request.
+     * Gets the stored fields to load and return as part of the search request.
      */
-    public List<String> fields() {
-        return fieldNames;
+    public List<String> storedFields() {
+        return storedFieldNames;
     }
 
+
     /**
-     * Adds a field to load from the field data cache and return as part of the
+     * Adds a field to load from the docvalue and return as part of the
      * search request.
+     *
+     * @deprecated Use {@link SearchSourceBuilder#docValueField(String)} instead.
      */
+    @Deprecated
     public SearchSourceBuilder fieldDataField(String name) {
-        if (fieldDataFields == null) {
-            fieldDataFields = new ArrayList<>();
+        if (docValueFields == null) {
+            docValueFields = new ArrayList<>();
         }
-        fieldDataFields.add(name);
+        docValueFields.add(name);
         return this;
     }
 
     /**
-     * Gets the field-data fields.
+     * Gets the docvalue fields.
+     *
+     * @deprecated Use {@link SearchSourceBuilder#docValueFields()} instead.
      */
+    @Deprecated
     public List<String> fieldDataFields() {
-        return fieldDataFields;
+        return docValueFields;
+    }
+
+
+    /**
+     * Gets the docvalue fields.
+     */
+    public List<String> docValueFields() {
+        return docValueFields;
+    }
+
+    /**
+     * Adds a field to load from the docvalue and return as part of the
+     * search request.
+     */
+    public SearchSourceBuilder docValueField(String name) {
+        if (docValueFields == null) {
+            docValueFields = new ArrayList<>();
+        }
+        docValueFields.add(name);
+        return this;
     }
 
     /**
@@ -911,8 +911,8 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
             rewrittenBuilder.explain = explain;
             rewrittenBuilder.ext = ext;
             rewrittenBuilder.fetchSourceContext = fetchSourceContext;
-            rewrittenBuilder.fieldDataFields = fieldDataFields;
-            rewrittenBuilder.fieldNames = fieldNames;
+            rewrittenBuilder.docValueFields = docValueFields;
+            rewrittenBuilder.storedFieldNames = storedFieldNames;
             rewrittenBuilder.from = from;
             rewrittenBuilder.highlightBuilder = highlightBuilder;
             rewrittenBuilder.indexBoost = indexBoost;
@@ -972,12 +972,16 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
                     trackScores = parser.booleanValue();
                 } else if (context.getParseFieldMatcher().match(currentFieldName, _SOURCE_FIELD)) {
                     fetchSourceContext = FetchSourceContext.parse(context);
-                } else if (context.getParseFieldMatcher().match(currentFieldName, FIELDS_FIELD)) {
-                    field(parser.text());
+                } else if (context.getParseFieldMatcher().match(currentFieldName, STORED_FIELDS_FIELD)) {
+                    storedField(parser.text());
                 } else if (context.getParseFieldMatcher().match(currentFieldName, SORT_FIELD)) {
                     sort(parser.text());
                 } else if (context.getParseFieldMatcher().match(currentFieldName, PROFILE_FIELD)) {
                     profile = parser.booleanValue();
+                } else if (context.getParseFieldMatcher().match(currentFieldName, FIELDS_FIELD)) {
+                    throw new ParsingException(parser.getTokenLocation(), "Deprecated field [" +
+                        SearchSourceBuilder.FIELDS_FIELD + "] used, expected [" +
+                        SearchSourceBuilder.STORED_FIELDS_FIELD + "] instead");
                 } else {
                     throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName + "].",
                             parser.getTokenLocation());
@@ -1027,22 +1031,21 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
                             parser.getTokenLocation());
                 }
             } else if (token == XContentParser.Token.START_ARRAY) {
-
-                if (context.getParseFieldMatcher().match(currentFieldName, FIELDS_FIELD)) {
-                    fieldNames = new ArrayList<>();
+                if (context.getParseFieldMatcher().match(currentFieldName, STORED_FIELDS_FIELD)) {
+                    storedFieldNames = new ArrayList<>();
                     while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
                         if (token == XContentParser.Token.VALUE_STRING) {
-                            fieldNames.add(parser.text());
+                            storedFieldNames.add(parser.text());
                         } else {
                             throw new ParsingException(parser.getTokenLocation(), "Expected [" + XContentParser.Token.VALUE_STRING + "] in ["
                                     + currentFieldName + "] but found [" + token + "]", parser.getTokenLocation());
                         }
                     }
-                } else if (context.getParseFieldMatcher().match(currentFieldName, FIELDDATA_FIELDS_FIELD)) {
-                    fieldDataFields = new ArrayList<>();
+                } else if (context.getParseFieldMatcher().match(currentFieldName, DOCVALUE_FIELDS_FIELD)) {
+                    docValueFields = new ArrayList<>();
                     while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
                         if (token == XContentParser.Token.VALUE_STRING) {
-                            fieldDataFields.add(parser.text());
+                            docValueFields.add(parser.text());
                         } else {
                             throw new ParsingException(parser.getTokenLocation(), "Expected [" + XContentParser.Token.VALUE_STRING + "] in ["
                                     + currentFieldName + "] but found [" + token + "]", parser.getTokenLocation());
@@ -1069,6 +1072,11 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
                     fetchSourceContext = FetchSourceContext.parse(context);
                 } else if (context.getParseFieldMatcher().match(currentFieldName, SEARCH_AFTER)) {
                     searchAfterBuilder = SearchAfterBuilder.fromXContent(parser, context.getParseFieldMatcher());
+                } else if (context.getParseFieldMatcher().match(currentFieldName, FIELDS_FIELD)) {
+                    throw new ParsingException(parser.getTokenLocation(), "The field [" +
+                        SearchSourceBuilder.FIELDS_FIELD + "] is not longer supported, please use [" +
+                        SearchSourceBuilder.STORED_FIELDS_FIELD + "] to retrieve stored fields or _source filtering " +
+                        "if the field is not stored");
                 } else {
                     throw new ParsingException(parser.getTokenLocation(), "Unknown key for a " + token + " in [" + currentFieldName + "].",
                             parser.getTokenLocation());
@@ -1132,21 +1140,21 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
             builder.field(_SOURCE_FIELD.getPreferredName(), fetchSourceContext);
         }
 
-        if (fieldNames != null) {
-            if (fieldNames.size() == 1) {
-                builder.field(FIELDS_FIELD.getPreferredName(), fieldNames.get(0));
+        if (storedFieldNames != null) {
+            if (storedFieldNames.size() == 1) {
+                builder.field(STORED_FIELDS_FIELD.getPreferredName(), storedFieldNames.get(0));
             } else {
-                builder.startArray(FIELDS_FIELD.getPreferredName());
-                for (String fieldName : fieldNames) {
+                builder.startArray(STORED_FIELDS_FIELD.getPreferredName());
+                for (String fieldName : storedFieldNames) {
                     builder.value(fieldName);
                 }
                 builder.endArray();
             }
         }
 
-        if (fieldDataFields != null) {
-            builder.startArray(FIELDDATA_FIELDS_FIELD.getPreferredName());
-            for (String fieldDataField : fieldDataFields) {
+        if (docValueFields != null) {
+            builder.startArray(DOCVALUE_FIELDS_FIELD.getPreferredName());
+            for (String fieldDataField : docValueFields) {
                 builder.value(fieldDataField);
             }
             builder.endArray();
@@ -1340,7 +1348,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
 
     @Override
     public int hashCode() {
-        return Objects.hash(aggregations, explain, fetchSourceContext, fieldDataFields, fieldNames, from,
+        return Objects.hash(aggregations, explain, fetchSourceContext, docValueFields, storedFieldNames, from,
                 highlightBuilder, indexBoost, minScore, postQueryBuilder, queryBuilder, rescoreBuilders, scriptFields,
                 size, sorts, searchAfterBuilder, sliceBuilder, stats, suggestBuilder, terminateAfter, timeoutInMillis, trackScores, version, profile);
     }
@@ -1357,8 +1365,8 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
         return Objects.equals(aggregations, other.aggregations)
                 && Objects.equals(explain, other.explain)
                 && Objects.equals(fetchSourceContext, other.fetchSourceContext)
-                && Objects.equals(fieldDataFields, other.fieldDataFields)
-                && Objects.equals(fieldNames, other.fieldNames)
+                && Objects.equals(docValueFields, other.docValueFields)
+                && Objects.equals(storedFieldNames, other.storedFieldNames)
                 && Objects.equals(from, other.from)
                 && Objects.equals(highlightBuilder, other.highlightBuilder)
                 && Objects.equals(indexBoost, other.indexBoost)

+ 1 - 1
core/src/test/java/org/elasticsearch/index/IndexWithShadowReplicasIT.java

@@ -677,7 +677,7 @@ public class IndexWithShadowReplicasIT extends ESIntegTestCase {
         client().prepareIndex(IDX, "doc", "4").setSource("foo", "eggplant").get();
         flushAndRefresh(IDX);
 
-        SearchResponse resp = client().prepareSearch(IDX).setQuery(matchAllQuery()).addFieldDataField("foo").addSort("foo", SortOrder.ASC).get();
+        SearchResponse resp = client().prepareSearch(IDX).setQuery(matchAllQuery()).addDocValueField("foo").addSort("foo", SortOrder.ASC).get();
         assertHitCount(resp, 4);
         assertOrderedSearchHits(resp, "2", "3", "4", "1");
         SearchHit[] hits = resp.getHits().hits();

+ 2 - 2
core/src/test/java/org/elasticsearch/index/mapper/core/TokenCountFieldMapperIntegrationIT.java

@@ -166,9 +166,9 @@ public class TokenCountFieldMapperIntegrationIT extends ESIntegTestCase {
 
     private SearchRequestBuilder prepareSearch() {
         SearchRequestBuilder request = client().prepareSearch("test").setTypes("test");
-        request.addField("foo.token_count");
+        request.addStoredField("foo.token_count");
         if (loadCountedFields) {
-            request.addField("foo");
+            request.addStoredField("foo");
         }
         return request;
     }

+ 4 - 4
core/src/test/java/org/elasticsearch/index/mapper/geo/GeoPointFieldMapperTests.java

@@ -816,7 +816,7 @@ public class GeoPointFieldMapperTests extends ESSingleNodeTestCase {
                 .field("lon", -74.0059731).endObject().endObject()).setRefreshPolicy(IMMEDIATE).get();
 
         // match all search with geohash field
-        SearchResponse searchResponse = client().prepareSearch().addField("location.geohash").setQuery(matchAllQuery()).execute().actionGet();
+        SearchResponse searchResponse = client().prepareSearch().addStoredField("location.geohash").setQuery(matchAllQuery()).execute().actionGet();
         Map<String, SearchHitField> m = searchResponse.getHits().getAt(0).getFields();
 
         // ensure single geohash was indexed
@@ -841,7 +841,7 @@ public class GeoPointFieldMapperTests extends ESSingleNodeTestCase {
                 .field("lon", -74.0059731).endObject().endObject()).setRefreshPolicy(IMMEDIATE).get();
 
         // match all search with geohash field (includes prefixes)
-        SearchResponse searchResponse = client().prepareSearch().addField("location.geohash").setQuery(matchAllQuery()).execute().actionGet();
+        SearchResponse searchResponse = client().prepareSearch().addStoredField("location.geohash").setQuery(matchAllQuery()).execute().actionGet();
         Map<String, SearchHitField> m = searchResponse.getHits().getAt(0).getFields();
 
         List<Object> hashes = m.get("location.geohash").values();
@@ -872,11 +872,11 @@ public class GeoPointFieldMapperTests extends ESSingleNodeTestCase {
         }
 
         // query by geohash subfield
-        SearchResponse searchResponse = client().prepareSearch().addField("location.geohash").setQuery(matchAllQuery()).execute().actionGet();
+        SearchResponse searchResponse = client().prepareSearch().addStoredField("location.geohash").setQuery(matchAllQuery()).execute().actionGet();
         assertEquals(numDocs, searchResponse.getHits().totalHits());
 
         // query by latlon subfield
-        searchResponse = client().prepareSearch().addField("location.latlon").setQuery(matchAllQuery()).execute().actionGet();
+        searchResponse = client().prepareSearch().addStoredField("location.latlon").setQuery(matchAllQuery()).execute().actionGet();
         assertEquals(numDocs, searchResponse.getHits().totalHits());
     }
 }

+ 7 - 7
core/src/test/java/org/elasticsearch/index/query/InnerHitBuilderTests.java

@@ -218,8 +218,8 @@ public class InnerHitBuilderTests extends ESTestCase {
         innerHits.setExplain(randomBoolean());
         innerHits.setVersion(randomBoolean());
         innerHits.setTrackScores(randomBoolean());
-        innerHits.setFieldNames(randomListStuff(16, () -> randomAsciiOfLengthBetween(1, 16)));
-        innerHits.setFieldDataFields(randomListStuff(16, () -> randomAsciiOfLengthBetween(1, 16)));
+        innerHits.setStoredFieldNames(randomListStuff(16, () -> randomAsciiOfLengthBetween(1, 16)));
+        innerHits.setDocValueFields(randomListStuff(16, () -> randomAsciiOfLengthBetween(1, 16)));
         // Random script fields deduped on their field name.
         Map<String, SearchSourceBuilder.ScriptField> scriptFields = new HashMap<>();
         for (SearchSourceBuilder.ScriptField field: randomListStuff(16, InnerHitBuilderTests::randomScript)) {
@@ -294,11 +294,11 @@ public class InnerHitBuilderTests extends ESTestCase {
                 break;
             case 6:
                 if (randomBoolean()) {
-                    instance.setFieldDataFields(randomValueOtherThan(instance.getFieldDataFields(), () -> {
+                    instance.setDocValueFields(randomValueOtherThan(instance.getDocValueFields(), () -> {
                         return randomListStuff(16, () -> randomAsciiOfLengthBetween(1, 16));
                     }));
                 } else {
-                    instance.addFieldDataField(randomAsciiOfLengthBetween(1, 16));
+                    instance.addDocValueField(randomAsciiOfLengthBetween(1, 16));
                 }
                 break;
             case 7:
@@ -341,12 +341,12 @@ public class InnerHitBuilderTests extends ESTestCase {
                         HighlightBuilderTests::randomHighlighterBuilder));
                 break;
             case 11:
-                if (instance.getFieldNames() == null || randomBoolean()) {
-                    instance.setFieldNames(randomValueOtherThan(instance.getFieldNames(), () -> {
+                if (instance.getStoredFieldNames() == null || randomBoolean()) {
+                    instance.setStoredFieldNames(randomValueOtherThan(instance.getStoredFieldNames(), () -> {
                         return randomListStuff(16, () -> randomAsciiOfLengthBetween(1, 16));
                     }));
                 } else {
-                    instance.getFieldNames().add(randomAsciiOfLengthBetween(1, 16));
+                    instance.getStoredFieldNames().add(randomAsciiOfLengthBetween(1, 16));
                 }
                 break;
             default:

+ 1 - 1
core/src/test/java/org/elasticsearch/index/store/ExceptionRetryIT.java

@@ -113,7 +113,7 @@ public class ExceptionRetryIT extends ESIntegTestCase {
         }
 
         refresh();
-        SearchResponse searchResponse = client().prepareSearch("index").setSize(numDocs * 2).addField("_id").get();
+        SearchResponse searchResponse = client().prepareSearch("index").setSize(numDocs * 2).addStoredField("_id").get();
 
         Set<String> uniqueIds = new HashSet();
         long dupCounter = 0;

+ 2 - 2
core/src/test/java/org/elasticsearch/indices/template/SimpleIndexTemplateIT.java

@@ -116,7 +116,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
         ensureGreen();
         SearchResponse searchResponse = client().prepareSearch("test_index")
                 .setQuery(termQuery("field1", "value1"))
-                .addField("field1").addField("field2")
+                .addStoredField("field1").addStoredField("field2")
                 .execute().actionGet();
 
         assertHitCount(searchResponse, 1);
@@ -130,7 +130,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
         // now only match on one template (template_1)
         searchResponse = client().prepareSearch("text_index")
                 .setQuery(termQuery("field1", "value1"))
-                .addField("field1").addField("field2")
+                .addStoredField("field1").addStoredField("field2")
                 .execute().actionGet();
         if (searchResponse.getFailedShards() > 0) {
             logger.warn("failed search {}", Arrays.toString(searchResponse.getShardFailures()));

+ 1 - 1
core/src/test/java/org/elasticsearch/recovery/RelocationIT.java

@@ -219,7 +219,7 @@ public class RelocationIT extends ESIntegTestCase {
             for (int i = 0; i < 10; i++) {
                 try {
                     logger.info("--> START search test round {}", i + 1);
-                    SearchHits hits = client().prepareSearch("test").setQuery(matchAllQuery()).setSize((int) indexer.totalIndexedDocs()).setNoFields().execute().actionGet().getHits();
+                    SearchHits hits = client().prepareSearch("test").setQuery(matchAllQuery()).setSize((int) indexer.totalIndexedDocs()).setNoStoredFields().execute().actionGet().getHits();
                     ranOnce = true;
                     if (hits.totalHits() != indexer.totalIndexedDocs()) {
                         int[] hitIds = new int[(int) indexer.totalIndexedDocs()];

+ 1 - 1
core/src/test/java/org/elasticsearch/search/aggregations/metrics/AbstractGeoTestCase.java

@@ -181,7 +181,7 @@ public abstract class AbstractGeoTestCase extends ESIntegTestCase {
         // Added to debug a test failure where the terms aggregation seems to be reporting two documents with the same value for NUMBER_FIELD_NAME.  This will check that after
         // random indexing each document only has 1 value for NUMBER_FIELD_NAME and it is the correct value. Following this initial change its seems that this call was getting
         // more that 2000 hits (actual value was 2059) so now it will also check to ensure all hits have the correct index and type
-        SearchResponse response = client().prepareSearch(HIGH_CARD_IDX_NAME).addField(NUMBER_FIELD_NAME).addSort(SortBuilders.fieldSort(NUMBER_FIELD_NAME)
+        SearchResponse response = client().prepareSearch(HIGH_CARD_IDX_NAME).addStoredField(NUMBER_FIELD_NAME).addSort(SortBuilders.fieldSort(NUMBER_FIELD_NAME)
                 .order(SortOrder.ASC)).setSize(5000).get();
         assertSearchResponse(response);
         long totalHits = response.getHits().totalHits();

+ 2 - 2
core/src/test/java/org/elasticsearch/search/builder/SearchSourceBuilderTests.java

@@ -219,12 +219,12 @@ public class SearchSourceBuilderTests extends ESTestCase {
             for (int i = 0; i < fieldsSize; i++) {
                 fields.add(randomAsciiOfLengthBetween(5, 50));
             }
-            builder.fields(fields);
+            builder.storedFields(fields);
         }
         if (randomBoolean()) {
             int fieldDataFieldsSize = randomInt(25);
             for (int i = 0; i < fieldDataFieldsSize; i++) {
-                builder.fieldDataField(randomAsciiOfLengthBetween(5, 50));
+                builder.docValueField(randomAsciiOfLengthBetween(5, 50));
             }
         }
         if (randomBoolean()) {

+ 4 - 4
core/src/test/java/org/elasticsearch/search/child/ChildQuerySearchIT.java

@@ -202,7 +202,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
         refresh();
 
         // TEST FETCHING _parent from child
-        SearchResponse searchResponse = client().prepareSearch("test").setQuery(idsQuery("child").addIds("c1")).fields("_parent").execute()
+        SearchResponse searchResponse = client().prepareSearch("test").setQuery(idsQuery("child").addIds("c1")).storedFields("_parent").execute()
                 .actionGet();
         assertNoFailures(searchResponse);
         assertThat(searchResponse.getHits().totalHits(), equalTo(1L));
@@ -210,7 +210,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
         assertThat(searchResponse.getHits().getAt(0).field("_parent").value().toString(), equalTo("p1"));
 
         // TEST matching on parent
-        searchResponse = client().prepareSearch("test").setQuery(termQuery("_parent#parent", "p1")).fields("_parent").get();
+        searchResponse = client().prepareSearch("test").setQuery(termQuery("_parent#parent", "p1")).storedFields("_parent").get();
         assertNoFailures(searchResponse);
         assertThat(searchResponse.getHits().totalHits(), equalTo(2L));
         assertThat(searchResponse.getHits().getAt(0).id(), anyOf(equalTo("c1"), equalTo("c2")));
@@ -218,7 +218,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
         assertThat(searchResponse.getHits().getAt(1).id(), anyOf(equalTo("c1"), equalTo("c2")));
         assertThat(searchResponse.getHits().getAt(1).field("_parent").value().toString(), equalTo("p1"));
 
-        searchResponse = client().prepareSearch("test").setQuery(queryStringQuery("_parent#parent:p1")).fields("_parent").get();
+        searchResponse = client().prepareSearch("test").setQuery(queryStringQuery("_parent#parent:p1")).storedFields("_parent").get();
         assertNoFailures(searchResponse);
         assertThat(searchResponse.getHits().totalHits(), equalTo(2L));
         assertThat(searchResponse.getHits().getAt(0).id(), anyOf(equalTo("c1"), equalTo("c2")));
@@ -1394,7 +1394,7 @@ public class ChildQuerySearchIT extends ESIntegTestCase {
             SearchResponse scrollResponse = client().prepareSearch("test")
                     .setScroll(TimeValue.timeValueSeconds(30))
                     .setSize(1)
-                    .addField("_id")
+                    .addStoredField("_id")
                     .setQuery(query)
                     .execute()
                     .actionGet();

+ 2 - 2
core/src/test/java/org/elasticsearch/search/geo/GeoFilterIT.java

@@ -415,13 +415,13 @@ public class GeoFilterIT extends ESIntegTestCase {
             assertThat(hit.getId(), equalTo(key));
         }
 
-        SearchResponse world = client().prepareSearch().addField("pin").setQuery(
+        SearchResponse world = client().prepareSearch().addStoredField("pin").setQuery(
                 geoBoundingBoxQuery("pin").setCorners(90, -179.99999, -90, 179.99999)
         ).execute().actionGet();
 
         assertHitCount(world, 53);
 
-        SearchResponse distance = client().prepareSearch().addField("pin").setQuery(
+        SearchResponse distance = client().prepareSearch().addStoredField("pin").setQuery(
                 geoDistanceQuery("pin").distance("425km").point(51.11, 9.851)
                 ).execute().actionGet();
 

+ 2 - 2
core/src/test/java/org/elasticsearch/search/innerhits/InnerHitsIT.java

@@ -156,7 +156,7 @@ public class InnerHitsIT extends ESIntegTestCase {
                 .setQuery(nestedQuery("comments", matchQuery("comments.message", "fox"), ScoreMode.Avg).innerHit(
                         new InnerHitBuilder().setHighlightBuilder(new HighlightBuilder().field("comments.message"))
                                 .setExplain(true)
-                                .addFieldDataField("comments.message")
+                                .addDocValueField("comments.message")
                                 .addScriptField("script", new Script("5", ScriptService.ScriptType.INLINE, MockScriptEngine.NAME, Collections.emptyMap()))
                                 .setSize(1)
                 )).get();
@@ -287,7 +287,7 @@ public class InnerHitsIT extends ESIntegTestCase {
                 .setQuery(
                         hasChildQuery("comment", matchQuery("message", "fox"), ScoreMode.None).innerHit(
                                 new InnerHitBuilder()
-                                        .addFieldDataField("message")
+                                        .addDocValueField("message")
                                         .setHighlightBuilder(new HighlightBuilder().field("message"))
                                         .setExplain(true).setSize(1)
                                         .addScriptField("script", new Script("5", ScriptService.ScriptType.INLINE,

+ 2 - 2
core/src/test/java/org/elasticsearch/search/source/SourceFetchingIT.java

@@ -37,10 +37,10 @@ public class SourceFetchingIT extends ESIntegTestCase {
         SearchResponse response = client().prepareSearch("test").get();
         assertThat(response.getHits().getAt(0).getSourceAsString(), notNullValue());
 
-        response = client().prepareSearch("test").addField("bla").get();
+        response = client().prepareSearch("test").addStoredField("bla").get();
         assertThat(response.getHits().getAt(0).getSourceAsString(), nullValue());
 
-        response = client().prepareSearch("test").addField("_source").get();
+        response = client().prepareSearch("test").addStoredField("_source").get();
         assertThat(response.getHits().getAt(0).getSourceAsString(), notNullValue());
 
     }

+ 1 - 1
core/src/test/java/org/elasticsearch/update/TimestampTTLBWIT.java

@@ -87,7 +87,7 @@ public class TimestampTTLBWIT extends ESIntegTestCase {
                 .setQuery(matchAllQuery())
                 .setSize(randomIntBetween(1, numDocs + 5))
                 .addSort("_timestamp", order)
-                .addField("_timestamp")
+                .addStoredField("_timestamp")
                 .execute().actionGet();
         assertNoFailures(searchResponse);
         SearchHit[] hits = searchResponse.getHits().hits();

+ 2 - 2
docs/plugins/mapper-attachments.asciidoc

@@ -246,7 +246,7 @@ PUT /test/person/1?refresh=true
 }
 GET /test/person/_search
 {
-  "fields": [ "file.content_type" ],
+  "stored_fields": [ "file.content_type" ],
   "query": {
     "match": {
       "file.content_type": "text plain"
@@ -367,7 +367,7 @@ PUT /test/person/1?refresh=true
 }
 GET /test/person/_search
 {
-  "fields": [],
+  "stored_fields": [],
   "query": {
     "match": {
       "file.content": "king queen"

+ 1 - 1
docs/reference/aggregations/metrics/tophits-aggregation.asciidoc

@@ -22,7 +22,7 @@ The top_hits aggregation returns regular search hits, because of this many per h
 * <<search-request-named-queries-and-filters,Named filters and queries>>
 * <<search-request-source-filtering,Source filtering>>
 * <<search-request-script-fields,Script fields>>
-* <<search-request-fielddata-fields,Fielddata fields>>
+* <<search-request-docvalue-fields,Doc value fields>>
 * <<search-request-version,Include versions>>
 
 ==== Example

+ 1 - 1
docs/reference/mapping/params/store.asciidoc

@@ -48,7 +48,7 @@ PUT my_index/my_type/1
 
 GET my_index/_search
 {
-  "fields": [ "title", "date" ] <2>
+  "stored_fields": [ "title", "date" ] <2>
 }
 --------------------------------------------------
 // CONSOLE

+ 7 - 3
docs/reference/migration/migrate_5_0/search.asciidoc

@@ -64,11 +64,15 @@ characteristics as the former `scan` search type.
 
 ==== `fields` parameter
 
-The `fields` parameter used to try to retrieve field values from stored
-fields, and fall back to extracting from the `_source` if a field is not
-marked as stored.  Now, the `fields` parameter will only return stored fields
+The `fields` parameter has been replaced by `stored_fields`.
+The `stored_fields` parameter will only return stored fields
 -- it will no longer extract values from the `_source`.
 
+==== `fielddata_fields` parameter
+
+The `fielddata_fields` has been deprecated, use parameter `docvalue_fields` instead.
+
+
 ==== search-exists API removed
 
 The search exists api has been removed in favour of using the search api with

+ 1 - 1
docs/reference/modules/scripting/painless.asciidoc

@@ -152,7 +152,7 @@ First, let's look at the source data for a player by submitting the following re
 ----------------------------------------------------------------
 GET hockey/_search
 {
-  "fields": [
+  "stored_fields": [
     "_id",
     "_source"
   ],

+ 2 - 2
docs/reference/search/request-body.asciidoc

@@ -143,11 +143,11 @@ include::request/sort.asciidoc[]
 
 include::request/source-filtering.asciidoc[]
 
-include::request/fields.asciidoc[]
+include::request/stored-fields.asciidoc[]
 
 include::request/script-fields.asciidoc[]
 
-include::request/fielddata-fields.asciidoc[]
+include::request/docvalue-fields.asciidoc[]
 
 include::request/post-filter.asciidoc[]
 

+ 23 - 0
docs/reference/search/request/docvalue-fields.asciidoc

@@ -0,0 +1,23 @@
+[[search-request-docvalue-fields]]
+=== Doc value Fields
+
+Allows to return the <<docvalue,doc value>> representation of a field for each hit, for
+example:
+
+[source,js]
+--------------------------------------------------
+GET /_search
+{
+    "query" : {
+        "match_all": {}
+    },
+    "docvalue_fields" : ["test1", "test2"]
+}
+--------------------------------------------------
+// CONSOLE
+
+Doc value fields can work on fields that are not stored.
+
+Note that if the fields parameter specifies fields without docvalues it will try to load the value from the fielddata cache
+causing the terms for that field to be loaded to memory (cached), which will result in more memory consumption.
+

+ 0 - 23
docs/reference/search/request/fielddata-fields.asciidoc

@@ -1,23 +0,0 @@
-[[search-request-fielddata-fields]]
-=== Field Data Fields
-
-Allows to return the <<fielddata,field data>> representation of a field for each hit, for
-example:
-
-[source,js]
---------------------------------------------------
-GET /_search
-{
-    "query" : {
-        "match_all": {}
-    },
-    "fielddata_fields" : ["test1", "test2"]
-}
---------------------------------------------------
-// CONSOLE
-
-Field data fields can work on fields that are not stored.
-
-It's important to understand that using the `fielddata_fields` parameter will
-cause the terms for that field to be loaded to memory (cached), which will
-result in more memory consumption.

+ 1 - 1
docs/reference/search/request/highlighting.asciidoc

@@ -372,7 +372,7 @@ query and the rescore query in `highlight_query`.
 --------------------------------------------------
 GET /_search
 {
-    "fields": [ "_id" ],
+    "stored_fields": [ "_id" ],
     "query" : {
         "match": {
             "content": {

+ 1 - 1
docs/reference/search/request/inner-hits.asciidoc

@@ -72,7 +72,7 @@ Inner hits also supports the following per document features:
 * <<search-request-explain,Explain>>
 * <<search-request-source-filtering,Source filtering>>
 * <<search-request-script-fields,Script fields>>
-* <<search-request-fielddata-fields,Fielddata fields>>
+* <<search-request-docvalue-fields,Doc value fields>>
 * <<search-request-version,Include versions>>
 
 [[nested-inner-hits]]

+ 3 - 3
docs/reference/search/request/fields.asciidoc → docs/reference/search/request/stored-fields.asciidoc

@@ -1,7 +1,7 @@
 [[search-request-fields]]
 === Fields
 
-WARNING: The `fields` parameter is about fields that are explicitly marked as
+WARNING: The `stored_fields` parameter is about fields that are explicitly marked as
 stored in the mapping, which is off by default and generally not recommended.
 Use <<search-request-source-filtering,source filtering>> instead to select
 subsets of the original source document to be returned.
@@ -13,7 +13,7 @@ by a search hit.
 --------------------------------------------------
 GET /_search
 {
-    "fields" : ["user", "postDate"],
+    "stored_fields" : ["user", "postDate"],
     "query" : {
         "term" : { "user" : "kimchy" }
     }
@@ -30,7 +30,7 @@ returned, for example:
 --------------------------------------------------
 GET /_search
 {
-    "fields" : [],
+    "stored_fields" : [],
     "query" : {
         "term" : { "user" : "kimchy" }
     }

+ 1 - 1
docs/reference/search/uri-request.asciidoc

@@ -83,7 +83,7 @@ hits was computed.
 part of the document by using `_source_include` & `_source_exclude` (see the <<search-request-source-filtering, request body>>
 documentation for more details)
 
-|`fields` |The selective stored fields of the document to return for each hit,
+|`stored_fields` |The selective stored fields of the document to return for each hit,
 comma delimited. Not specifying any value will cause no fields to return.
 
 |`sort` |Sorting to perform. Can either be in the form of `fieldName`, or

+ 8 - 8
modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/GeoDistanceTests.java

@@ -72,28 +72,28 @@ public class GeoDistanceTests extends ESIntegTestCase {
 
         refresh();
 
-        SearchResponse searchResponse1 = client().prepareSearch().addField("_source")
+        SearchResponse searchResponse1 = client().prepareSearch().addStoredField("_source")
                 .addScriptField("distance", new Script("doc['location'].arcDistance(" + target_lat + "," + target_long + ")")).execute()
                 .actionGet();
         Double resultDistance1 = searchResponse1.getHits().getHits()[0].getFields().get("distance").getValue();
         assertThat(resultDistance1,
                 closeTo(GeoDistance.ARC.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.DEFAULT), 0.01d));
 
-        SearchResponse searchResponse2 = client().prepareSearch().addField("_source")
+        SearchResponse searchResponse2 = client().prepareSearch().addStoredField("_source")
                 .addScriptField("distance", new Script("doc['location'].distance(" + target_lat + "," + target_long + ")")).execute()
                 .actionGet();
         Double resultDistance2 = searchResponse2.getHits().getHits()[0].getFields().get("distance").getValue();
         assertThat(resultDistance2,
                 closeTo(GeoDistance.PLANE.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.DEFAULT), 0.01d));
 
-        SearchResponse searchResponse3 = client().prepareSearch().addField("_source")
+        SearchResponse searchResponse3 = client().prepareSearch().addStoredField("_source")
                 .addScriptField("distance", new Script("doc['location'].arcDistanceInKm(" + target_lat + "," + target_long + ")"))
                 .execute().actionGet();
         Double resultArcDistance3 = searchResponse3.getHits().getHits()[0].getFields().get("distance").getValue();
         assertThat(resultArcDistance3,
                 closeTo(GeoDistance.ARC.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.KILOMETERS), 0.01d));
 
-        SearchResponse searchResponse4 = client().prepareSearch().addField("_source")
+        SearchResponse searchResponse4 = client().prepareSearch().addStoredField("_source")
                 .addScriptField("distance", new Script("doc['location'].distanceInKm(" + target_lat + "," + target_long + ")")).execute()
                 .actionGet();
         Double resultDistance4 = searchResponse4.getHits().getHits()[0].getFields().get("distance").getValue();
@@ -102,7 +102,7 @@ public class GeoDistanceTests extends ESIntegTestCase {
 
         SearchResponse searchResponse5 = client()
                 .prepareSearch()
-                .addField("_source")
+                .addStoredField("_source")
                 .addScriptField("distance", new Script("doc['location'].arcDistanceInKm(" + (target_lat) + "," + (target_long + 360) + ")"))
                 .execute().actionGet();
         Double resultArcDistance5 = searchResponse5.getHits().getHits()[0].getFields().get("distance").getValue();
@@ -111,21 +111,21 @@ public class GeoDistanceTests extends ESIntegTestCase {
 
         SearchResponse searchResponse6 = client()
                 .prepareSearch()
-                .addField("_source")
+                .addStoredField("_source")
                 .addScriptField("distance", new Script("doc['location'].arcDistanceInKm(" + (target_lat + 360) + "," + (target_long) + ")"))
                 .execute().actionGet();
         Double resultArcDistance6 = searchResponse6.getHits().getHits()[0].getFields().get("distance").getValue();
         assertThat(resultArcDistance6,
                 closeTo(GeoDistance.ARC.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.KILOMETERS), 0.01d));
 
-        SearchResponse searchResponse7 = client().prepareSearch().addField("_source")
+        SearchResponse searchResponse7 = client().prepareSearch().addStoredField("_source")
                 .addScriptField("distance", new Script("doc['location'].arcDistanceInMiles(" + target_lat + "," + target_long + ")"))
                 .execute().actionGet();
         Double resultDistance7 = searchResponse7.getHits().getHits()[0].getFields().get("distance").getValue();
         assertThat(resultDistance7,
                 closeTo(GeoDistance.ARC.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.MILES), 0.01d));
 
-        SearchResponse searchResponse8 = client().prepareSearch().addField("_source")
+        SearchResponse searchResponse8 = client().prepareSearch().addStoredField("_source")
                 .addScriptField("distance", new Script("doc['location'].distanceInMiles(" + target_lat + "," + target_long + ")"))
                 .execute().actionGet();
         Double resultDistance8 = searchResponse8.getHits().getHits()[0].getFields().get("distance").getValue();

+ 33 - 33
modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SearchFieldsTests.java

@@ -102,33 +102,33 @@ public class SearchFieldsTests extends ESIntegTestCase {
 
         client().admin().indices().prepareRefresh().execute().actionGet();
 
-        SearchResponse searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addField("field1").execute().actionGet();
+        SearchResponse searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addStoredField("field1").execute().actionGet();
         assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
         assertThat(searchResponse.getHits().hits().length, equalTo(1));
         assertThat(searchResponse.getHits().getAt(0).fields().size(), equalTo(1));
         assertThat(searchResponse.getHits().getAt(0).fields().get("field1").value().toString(), equalTo("value1"));
 
         // field2 is not stored, check that it is not extracted from source.
-        searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addField("field2").execute().actionGet();
+        searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addStoredField("field2").execute().actionGet();
         assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
         assertThat(searchResponse.getHits().hits().length, equalTo(1));
         assertThat(searchResponse.getHits().getAt(0).fields().size(), equalTo(0));
         assertThat(searchResponse.getHits().getAt(0).fields().get("field2"), nullValue());
 
-        searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addField("field3").execute().actionGet();
+        searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addStoredField("field3").execute().actionGet();
         assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
         assertThat(searchResponse.getHits().hits().length, equalTo(1));
         assertThat(searchResponse.getHits().getAt(0).fields().size(), equalTo(1));
         assertThat(searchResponse.getHits().getAt(0).fields().get("field3").value().toString(), equalTo("value3"));
 
-        searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addField("*3").execute().actionGet();
+        searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addStoredField("*3").execute().actionGet();
         assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
         assertThat(searchResponse.getHits().hits().length, equalTo(1));
         assertThat(searchResponse.getHits().getAt(0).fields().size(), equalTo(1));
         assertThat(searchResponse.getHits().getAt(0).fields().get("field3").value().toString(), equalTo("value3"));
 
 
-        searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addField("*3").addField("field1").addField("field2").execute().actionGet();
+        searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addStoredField("*3").addStoredField("field1").addStoredField("field2").execute().actionGet();
         assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
         assertThat(searchResponse.getHits().hits().length, equalTo(1));
         assertThat(searchResponse.getHits().getAt(0).fields().size(), equalTo(2));
@@ -136,20 +136,20 @@ public class SearchFieldsTests extends ESIntegTestCase {
         assertThat(searchResponse.getHits().getAt(0).fields().get("field1").value().toString(), equalTo("value1"));
 
 
-        searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addField("field*").execute().actionGet();
+        searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addStoredField("field*").execute().actionGet();
         assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
         assertThat(searchResponse.getHits().hits().length, equalTo(1));
         assertThat(searchResponse.getHits().getAt(0).fields().size(), equalTo(2));
         assertThat(searchResponse.getHits().getAt(0).fields().get("field3").value().toString(), equalTo("value3"));
         assertThat(searchResponse.getHits().getAt(0).fields().get("field1").value().toString(), equalTo("value1"));
 
-        searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addField("f*3").execute().actionGet();
+        searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addStoredField("f*3").execute().actionGet();
         assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
         assertThat(searchResponse.getHits().hits().length, equalTo(1));
         assertThat(searchResponse.getHits().getAt(0).fields().size(), equalTo(1));
         assertThat(searchResponse.getHits().getAt(0).fields().get("field3").value().toString(), equalTo("value3"));
 
-        searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addField("*").execute().actionGet();
+        searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addStoredField("*").execute().actionGet();
         assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
         assertThat(searchResponse.getHits().hits().length, equalTo(1));
         assertThat(searchResponse.getHits().getAt(0).source(), nullValue());
@@ -157,7 +157,7 @@ public class SearchFieldsTests extends ESIntegTestCase {
         assertThat(searchResponse.getHits().getAt(0).fields().get("field1").value().toString(), equalTo("value1"));
         assertThat(searchResponse.getHits().getAt(0).fields().get("field3").value().toString(), equalTo("value3"));
 
-        searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addField("*").addField("_source").execute().actionGet();
+        searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addStoredField("*").addStoredField("_source").execute().actionGet();
         assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
         assertThat(searchResponse.getHits().hits().length, equalTo(1));
         assertThat(searchResponse.getHits().getAt(0).source(), notNullValue());
@@ -437,15 +437,15 @@ public class SearchFieldsTests extends ESIntegTestCase {
         client().admin().indices().prepareRefresh().execute().actionGet();
 
         SearchResponse searchResponse = client().prepareSearch().setQuery(matchAllQuery())
-                .addField("byte_field")
-                .addField("short_field")
-                .addField("integer_field")
-                .addField("long_field")
-                .addField("float_field")
-                .addField("double_field")
-                .addField("date_field")
-                .addField("boolean_field")
-                .addField("binary_field")
+                .addStoredField("byte_field")
+                .addStoredField("short_field")
+                .addStoredField("integer_field")
+                .addStoredField("long_field")
+                .addStoredField("float_field")
+                .addStoredField("double_field")
+                .addStoredField("date_field")
+                .addStoredField("boolean_field")
+                .addStoredField("binary_field")
                 .execute().actionGet();
 
         assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
@@ -478,7 +478,7 @@ public class SearchFieldsTests extends ESIntegTestCase {
 
         SearchResponse searchResponse = client().prepareSearch("my-index")
                 .setTypes("my-type1")
-                .addField("field1").addField("_routing")
+                .addStoredField("field1").addStoredField("_routing")
                 .get();
 
         assertThat(searchResponse.getHits().totalHits(), equalTo(1L));
@@ -493,7 +493,7 @@ public class SearchFieldsTests extends ESIntegTestCase {
                 .setRefreshPolicy(IMMEDIATE)
                 .get();
 
-        assertFailures(client().prepareSearch("my-index").setTypes("my-type1").addField("field1"),
+        assertFailures(client().prepareSearch("my-index").setTypes("my-type1").addStoredField("field1"),
                 RestStatus.BAD_REQUEST,
                 containsString("field [field1] isn't a leaf field"));
     }
@@ -557,14 +557,14 @@ public class SearchFieldsTests extends ESIntegTestCase {
 
 
         String field = "field1.field2.field3.field4";
-        SearchResponse searchResponse = client().prepareSearch("my-index").setTypes("my-type1").addField(field).get();
+        SearchResponse searchResponse = client().prepareSearch("my-index").setTypes("my-type1").addStoredField(field).get();
         assertThat(searchResponse.getHits().totalHits(), equalTo(1L));
         assertThat(searchResponse.getHits().getAt(0).field(field).isMetadataField(), equalTo(false));
         assertThat(searchResponse.getHits().getAt(0).field(field).getValues().size(), equalTo(2));
         assertThat(searchResponse.getHits().getAt(0).field(field).getValues().get(0).toString(), equalTo("value1"));
         assertThat(searchResponse.getHits().getAt(0).field(field).getValues().get(1).toString(), equalTo("value2"));
 
-        searchResponse = client().prepareSearch("my-index").setTypes("my-type2").addField(field).get();
+        searchResponse = client().prepareSearch("my-index").setTypes("my-type2").addStoredField(field).get();
         assertThat(searchResponse.getHits().totalHits(), equalTo(1L));
         assertThat(searchResponse.getHits().getAt(0).field(field).isMetadataField(), equalTo(false));
         assertThat(searchResponse.getHits().getAt(0).field(field).getValues().size(), equalTo(2));
@@ -621,16 +621,16 @@ public class SearchFieldsTests extends ESIntegTestCase {
         client().admin().indices().prepareRefresh().execute().actionGet();
 
         SearchRequestBuilder builder = client().prepareSearch().setQuery(matchAllQuery())
-                .addFieldDataField("text_field")
-                .addFieldDataField("keyword_field")
-                .addFieldDataField("byte_field")
-                .addFieldDataField("short_field")
-                .addFieldDataField("integer_field")
-                .addFieldDataField("long_field")
-                .addFieldDataField("float_field")
-                .addFieldDataField("double_field")
-                .addFieldDataField("date_field")
-                .addFieldDataField("boolean_field");
+                .addDocValueField("text_field")
+                .addDocValueField("keyword_field")
+                .addDocValueField("byte_field")
+                .addDocValueField("short_field")
+                .addDocValueField("integer_field")
+                .addDocValueField("long_field")
+                .addDocValueField("float_field")
+                .addDocValueField("double_field")
+                .addDocValueField("date_field")
+                .addDocValueField("boolean_field");
         SearchResponse searchResponse = builder.execute().actionGet();
 
         assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
@@ -704,7 +704,7 @@ public class SearchFieldsTests extends ESIntegTestCase {
                     .setParent("parent_1")
                     .setSource(jsonBuilder().startObject().field("field1", "value").endObject()));
 
-        SearchResponse response = client().prepareSearch("test").addField("field1").get();
+        SearchResponse response = client().prepareSearch("test").addStoredField("field1").get();
         assertSearchResponse(response);
         assertHitCount(response, 1);
 

+ 2 - 2
modules/reindex/src/main/java/org/elasticsearch/index/reindex/AbstractBulkByScrollRequest.java

@@ -123,8 +123,8 @@ public abstract class AbstractBulkByScrollRequest<Self extends AbstractBulkByScr
         if (searchRequest.source().from() != -1) {
             e = addValidationError("from is not supported in this context", e);
         }
-        if (searchRequest.source().fields() != null) {
-            e = addValidationError("fields is not supported in this context", e);
+        if (searchRequest.source().storedFields() != null) {
+            e = addValidationError("stored_fields is not supported in this context", e);
         }
         if (maxRetries < 0) {
             e = addValidationError("retries cannnot be negative", e);

+ 2 - 2
modules/reindex/src/test/resources/rest-api-spec/test/delete_by_query/20_validation.yaml

@@ -59,11 +59,11 @@
 ---
 "source fields may not be modified":
   - do:
-      catch: /fields is not supported in this context/
+      catch: /stored_fields is not supported in this context/
       delete_by_query:
         index: test
         body:
-          fields: [_id]
+          stored_fields: [_id]
 
 ---
 "requests_per_second cannot be an empty string":

+ 2 - 2
modules/reindex/src/test/resources/rest-api-spec/test/reindex/20_validation.yaml

@@ -216,11 +216,11 @@
 ---
 "source fields may not be modified":
   - do:
-      catch: /fields is not supported in this context/
+      catch: /stored_fields is not supported in this context/
       reindex:
         body:
           source:
             index: test
-            fields: [_id]
+            stored_fields: [_id]
           dest:
             index: dest

+ 2 - 2
modules/reindex/src/test/resources/rest-api-spec/test/update_by_query/20_validation.yaml

@@ -67,11 +67,11 @@
 ---
 "source fields may not be modified":
   - do:
-      catch: /fields is not supported in this context/
+      catch: /stored_fields is not supported in this context/
       update_by_query:
         index: test
         body:
-          fields: [_id]
+          stored_fields: [_id]
 
 ---
 "requests_per_second cannot be an empty string":

+ 1 - 1
plugins/mapper-attachments/src/test/resources/rest-api-spec/test/mapper_attachments/30_mapping.yaml

@@ -54,7 +54,7 @@
         search:
             index: test
             body:
-                fields: [file.content_type,file.name]
+                stored_fields: [file.content_type,file.name]
 
     - match: { hits.total: 1 }
     - match: { hits.hits.0.fields: { file.content_type: ["text/my-dummy-content-type"],  file.name: ["my-dummy-name-txt"] }}

+ 1 - 1
plugins/mapper-attachments/src/test/resources/rest-api-spec/test/mapper_attachments/40_highlight.yaml

@@ -57,7 +57,7 @@ setup:
                 query:
                     match:
                         file.content: "apache tika"
-                fields: []
+                stored_fields: []
                 highlight:
                   fields:
                     file.content: {}

+ 2 - 2
plugins/mapper-attachments/src/test/resources/rest-api-spec/test/mapper_attachments/50_files_supported.yaml

@@ -38,7 +38,7 @@ setup:
       search:
           index: test
           body:
-              fields: [file.content, file.author, file.date, file.content_length, file.content_type]
+              stored_fields: [file.content, file.author, file.date, file.content_length, file.content_type]
   - match: { hits.total: 1 }
   - match: { hits.hits.0.fields: {
       file.content: ["Test elasticsearch\n"],
@@ -65,7 +65,7 @@ setup:
       search:
           index: test
           body:
-              fields: [file.content, file.author, file.date, file.content_length, file.content_type]
+              stored_fields: [file.content, file.author, file.date, file.content_length, file.content_type]
   - match: { hits.total: 1 }
   - match: { hits.hits.0.fields: {
       file.content: ["Test elasticsearch\n"],

+ 2 - 2
plugins/mapper-size/src/test/java/org/elasticsearch/index/mapper/size/SizeFieldMapperUpgradeTests.java

@@ -83,8 +83,8 @@ public class SizeFieldMapperUpgradeTests extends ESIntegTestCase {
         ElasticsearchAssertions.assertHitCount(countResponse, 3L);
 
         final SearchResponse sizeResponse = client().prepareSearch(indexName)
-                .addField("_source")
-                .addField("_size")
+                .addStoredField("_source")
+                .addStoredField("_size")
                 .get();
         ElasticsearchAssertions.assertHitCount(sizeResponse, 3L);
         for (SearchHit hit : sizeResponse.getHits().getHits()) {

+ 7 - 3
rest-api-spec/src/main/resources/rest-api-spec/api/search.json

@@ -38,13 +38,17 @@
           "type" : "boolean",
           "description" : "Specify whether to return detailed information about score computation as part of a hit"
         },
-        "fields": {
+        "stored_fields": {
           "type" : "list",
-          "description" : "A comma-separated list of fields to return as part of a hit"
+          "description" : "A comma-separated list of stored fields to return as part of a hit"
+        },
+        "docvalue_fields": {
+          "type" : "list",
+          "description" : "A comma-separated list of fields to return as the docvalue representation of a field for each hit"
         },
         "fielddata_fields": {
           "type" : "list",
-          "description" : "A comma-separated list of fields to return as the field data representation of a field for each hit"
+          "description" : "A comma-separated list of fields to return as the docvalue representation of a field for each hit"
         },
         "from": {
           "type" : "number",

+ 7 - 2
rest-api-spec/src/main/resources/rest-api-spec/test/search/10_source_filtering.yaml

@@ -77,20 +77,25 @@
   - do:
       search:
         body:
-          fields: [ include.field2 ]
+          stored_fields: [ include.field2 ]
           query: { match_all: {} }
   - is_false:  hits.hits.0._source
 
   - do:
         search:
           body:
-            fields: [ include.field2, _source ]
+            stored_fields: [ include.field2, _source ]
             query: { match_all: {} }
   - match: { hits.hits.0._source.include.field2: v2 }
   - is_true:  hits.hits.0._source
 
+  - do:
+      search:
+        docvalue_fields: [ "count" ]
+  - match: { hits.hits.0.fields.count: [1] }
 
   - do:
       search:
         fielddata_fields: [ "count" ]
   - match: { hits.hits.0.fields.count: [1] }
+

+ 1 - 1
rest-api-spec/src/main/resources/rest-api-spec/test/search/issue4895.yaml

@@ -31,6 +31,6 @@ setup:
                   term:
                       data: some
                   preference: _local
-              fields: [user,amount]
+              stored_fields: [user,amount]