Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an include_type_name option. #29453

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions docs/reference/indices/create-index.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,28 @@ PUT test?wait_for_active_shards=2

A detailed explanation of `wait_for_active_shards` and its possible values can be found
<<index-wait-for-active-shards,here>>.

[float]
=== Skipping types

Types are scheduled to be fully removed in Elasticsearch 8.0 and will not appear
in requests or responses anymore. You can opt in for this future behaviour by
setting `include_type_name=false` and putting mappings directly under `mappings`
in the index creation call.

Here is an example:

[source,js]
--------------------------------------------------
PUT test?include_type_name=false
{
"mappings": {
"properties": {
"foo": {
"type": "keyword"
}
}
}
}
--------------------------------------------------
// CONSOLE
45 changes: 45 additions & 0 deletions docs/reference/indices/get-mapping.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,48 @@ GET /_mapping
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

[float]
=== Skipping types

Types are scheduled to be fully removed in Elasticsearch 8.0 and will not appear
in requests or responses anymore. You can opt in for this future behaviour by
setting `include_type_name=false` in the request, which will return mappings
directly under `mappings` without keying by the type name.

Here is an example:

[source,js]
--------------------------------------------------
PUT test?include_type_name=false
{
"mappings": {
"properties": {
"foo": {
"type": "keyword"
}
}
}
}

GET test/_mappings?include_type_name=false
--------------------------------------------------
// CONSOLE

which returns

[source,js]
--------------------------------------------------
{
"test": {
"mappings": {
"properties": {
"foo": {
"type": "keyword"
}
}
}
}
}
--------------------------------------------------
// TESTRESPONSE
51 changes: 51 additions & 0 deletions docs/reference/indices/put-mapping.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,54 @@ PUT my_index/_mapping/_doc

Each <<mapping-params,mapping parameter>> specifies whether or not its setting
can be updated on an existing field.

[float]
=== Skipping types

Types are scheduled to be fully removed in Elasticsearch 8.0 and will not appear
in requests or responses anymore. You can opt in for this future behaviour by
setting `include_type_name=false`.

NOTE: This should only be done on indices that have been created with
`include_type_name=false` or that used `_doc` as a type name.

The Console script from the above section is equivalent to the below invocation:

[source,js]
-----------------------------------
PUT my_index?include_type_name=false <1>
{
"mappings": {
"properties": {
"name": {
"properties": {
"first": {
"type": "text"
}
}
},
"user_id": {
"type": "keyword"
}
}
}
}

PUT my_index/_mapping?include_type_name=false
{
"properties": {
"name": {
"properties": {
"last": { <2>
"type": "text"
}
}
},
"user_id": {
"type": "keyword",
"ignore_above": 100 <3>
}
}
}
-----------------------------------
// CONSOLE
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
}
},
"params": {
"include_type_name": {
"type" : "string",
"description" : "Whether a type should be expected in the body of the mappings."
},
"wait_for_active_shards": {
"type" : "string",
"description" : "Set the number of active shards to wait for before the operation returns."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
}
},
"params": {
"include_type_name": {
"type" : "string",
"description" : "Whether to add the type name to the response"
},
"ignore_unavailable": {
"type" : "boolean",
"description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,22 @@
"methods": ["PUT", "POST"],
"url": {
"path": "/{index}/{type}/_mapping",
"paths": ["/{index}/{type}/_mapping", "/{index}/_mapping/{type}", "/_mapping/{type}", "/{index}/{type}/_mappings", "/{index}/_mappings/{type}", "/_mappings/{type}"],
"paths": ["/{index}/{type}/_mapping", "/{index}/_mapping/{type}", "/_mapping/{type}", "/{index}/{type}/_mappings", "/{index}/_mappings/{type}", "/_mappings/{type}", "{index}/_mappings", "{index}/_mapping"],
"parts": {
"index": {
"type" : "list",
"description" : "A comma-separated list of index names the mapping should be added to (supports wildcards); use `_all` or omit to add the mapping on all indices."
},
"type": {
"type" : "string",
"required" : true,
"description" : "The name of the document type"
}
},
"params": {
"include_type_name": {
"type" : "string",
"description" : "Whether a type should be expected in the body of the mappings."
},
"timeout": {
"type" : "time",
"description" : "Explicit operation timeout"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
"Create indices and manage mappings without types":

- skip:
version: " - 6.99.99"
reason: include_type_name was introduced in 7.0.0

- do:
indices.create:
index: index
include_type_name: false
body:
mappings:
properties:
foo:
type: keyword

- do:
indices.get_mapping:
index: index
include_type_name: false

- match: { index.mappings.properties.foo.type: "keyword" }

- do:
indices.put_mapping:
index: index
include_type_name: false
body:
properties:
bar:
type: float

- do:
indices.get_mapping:
index: index
include_type_name: false

- match: { index.mappings.properties.foo.type: "keyword" }
- match: { index.mappings.properties.bar.type: "float" }

---
"PUT mapping with a type and include_type_name: false":

- skip:
version: " - 6.99.99"
reason: include_type_name was introduced in 7.0.0

- do:
indices.create:
index: index

- do:
catch: /illegal_argument_exception/
indices.put_mapping:
index: index
type: _doc
include_type_name: false
body:
properties:
bar:
type: float

---
"Empty index with the include_type_name=false option":

- skip:
version: " - 6.99.99"
reason: include_type_name was introduced in 7.0.0

- do:
indices.create:
index: index
include_type_name: false

- do:
indices.get_mapping:
index: index
include_type_name: false

- match: { index.mappings: {} }
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,18 @@
import org.elasticsearch.action.support.ActiveShardCount;
import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.action.RestToXContentListener;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class RestCreateIndexAction extends BaseRestHandler {
public RestCreateIndexAction(Settings settings, RestController controller) {
Expand All @@ -43,9 +49,16 @@ public String getName() {

@Override
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
final boolean includeTypeName = request.paramAsBoolean("include_type_name", true);
CreateIndexRequest createIndexRequest = new CreateIndexRequest(request.param("index"));
if (request.hasContent()) {
createIndexRequest.source(request.content(), request.getXContentType());
Map<String, Object> sourceAsMap = XContentHelper.convertToMap(request.content(), false, request.getXContentType()).v2();
if (includeTypeName == false && sourceAsMap.containsKey("mappings")) {
Map<String, Object> newSourceAsMap = new HashMap<>(sourceAsMap);
newSourceAsMap.put("mappings", Collections.singletonMap(MapperService.SINGLE_MAPPING_NAME, sourceAsMap.get("mappings")));
sourceAsMap = newSourceAsMap;
}
createIndexRequest.source(sourceAsMap, LoggingDeprecationHandler.INSTANCE);
}
createIndexRequest.timeout(request.paramAsTime("timeout", createIndexRequest.timeout()));
createIndexRequest.masterNodeTimeout(request.paramAsTime("master_timeout", createIndexRequest.masterNodeTimeout()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public String getName() {

@Override
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
final boolean includeTypeName = request.paramAsBoolean("include_type_name", true);
final String[] indices = Strings.splitStringByCommaToArray(request.param("index"));
final String[] types = request.paramAsStringArrayOrEmptyIfAll("type");
final GetMappingsRequest getMappingsRequest = new GetMappingsRequest();
Expand Down Expand Up @@ -141,13 +142,29 @@ public RestResponse buildResponse(final GetMappingsResponse response, final XCon
for (final ObjectObjectCursor<String, ImmutableOpenMap<String, MappingMetaData>> indexEntry : mappingsByIndex) {
builder.startObject(indexEntry.key);
{
builder.startObject("mappings");
{
if (includeTypeName == false) {
MappingMetaData mappings = null;
for (final ObjectObjectCursor<String, MappingMetaData> typeEntry : indexEntry.value) {
builder.field(typeEntry.key, typeEntry.value.sourceAsMap());
if (typeEntry.key.equals("_default_") == false) {
assert mappings == null;
mappings = typeEntry.value;
}
}
if (mappings == null) {
// no mappings yet
builder.startObject("mappings").endObject();
} else {
builder.field("mappings", mappings.sourceAsMap());
}
} else {
builder.startObject("mappings");
{
for (final ObjectObjectCursor<String, MappingMetaData> typeEntry : indexEntry.value) {
builder.field(typeEntry.key, typeEntry.value.sourceAsMap());
}
}
builder.endObject();
}
builder.endObject();
}
builder.endObject();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
Expand Down Expand Up @@ -67,8 +68,13 @@ public String getName() {

@Override
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
final boolean includeTypeName = request.paramAsBoolean("include_type_name", true);
PutMappingRequest putMappingRequest = putMappingRequest(Strings.splitStringByCommaToArray(request.param("index")));
putMappingRequest.type(request.param("type"));
final String type = request.param("type");
if (type != null && includeTypeName == false) {
throw new IllegalArgumentException("Cannot set include_type_name=false and provide a type at the same time");
}
putMappingRequest.type(includeTypeName ? type : MapperService.SINGLE_MAPPING_NAME);
putMappingRequest.source(request.requiredContent(), request.getXContentType());
putMappingRequest.timeout(request.paramAsTime("timeout", putMappingRequest.timeout()));
putMappingRequest.masterNodeTimeout(request.paramAsTime("master_timeout", putMappingRequest.masterNodeTimeout()));
Expand Down