Add the `include_type_name` option to the search and document APIs. (#29506)
This commit add the `include_type_name` option to the `index`, `update`, `delete`, `get`, `bulk` and `search` APIs. When set to `false`, the response will omit the `_type` in the response. This option doesn't work if the endpoint contains a type. For instance, the following call would succeed: ``` GET index/_doc/1?include_type_name=false ``` But the following one would fail: ``` GET index/some_type/1?include_type_name=false ``` Relates #15613
This commit is contained in:
parent
fd161d2659
commit
d223bcf7ab
|
@ -16,6 +16,10 @@
|
|||
}
|
||||
},
|
||||
"params": {
|
||||
"include_type_name": {
|
||||
"type" : "string",
|
||||
"description" : "Whether to add the type name to the response"
|
||||
},
|
||||
"wait_for_active_shards": {
|
||||
"type" : "string",
|
||||
"description" : "Sets the number of shard copies that must be active before proceeding with the bulk operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1)"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"methods": ["DELETE"],
|
||||
"url": {
|
||||
"path": "/{index}/{type}/{id}",
|
||||
"paths": ["/{index}/{type}/{id}"],
|
||||
"paths": ["/{index}/{type}/{id}", "/{index}/_doc/{id}"],
|
||||
"parts": {
|
||||
"id": {
|
||||
"type" : "string",
|
||||
|
@ -18,11 +18,14 @@
|
|||
},
|
||||
"type": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"description" : "The type of the document"
|
||||
}
|
||||
},
|
||||
"params": {
|
||||
"include_type_name": {
|
||||
"type" : "string",
|
||||
"description" : "Whether to add the type name to the response"
|
||||
},
|
||||
"wait_for_active_shards": {
|
||||
"type" : "string",
|
||||
"description" : "Sets the number of shard copies that must be active before proceeding with the delete operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1)"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"methods": ["GET"],
|
||||
"url": {
|
||||
"path": "/{index}/{type}/{id}",
|
||||
"paths": ["/{index}/{type}/{id}"],
|
||||
"paths": ["/{index}/{type}/{id}", "/{index}/_doc/{id}"],
|
||||
"parts": {
|
||||
"id": {
|
||||
"type" : "string",
|
||||
|
@ -18,11 +18,14 @@
|
|||
},
|
||||
"type": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"description" : "The type of the document (use `_all` to fetch the first document matching the ID across all types)"
|
||||
}
|
||||
},
|
||||
"params": {
|
||||
"include_type_name": {
|
||||
"type" : "string",
|
||||
"description" : "Whether to add the type name to the response"
|
||||
},
|
||||
"stored_fields": {
|
||||
"type": "list",
|
||||
"description" : "A comma-separated list of stored fields to return in the response"
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
}
|
||||
},
|
||||
"params": {
|
||||
"include_type_name": {
|
||||
"type" : "string",
|
||||
"description" : "Whether to add the type name to the response"
|
||||
},
|
||||
"wait_for_active_shards": {
|
||||
"type" : "string",
|
||||
"description" : "Sets the number of shard copies that must be active before proceeding with the index operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1)"
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
}
|
||||
},
|
||||
"params": {
|
||||
"include_type_name": {
|
||||
"type" : "string",
|
||||
"description" : "Whether to add the type name to the response"
|
||||
},
|
||||
"analyzer": {
|
||||
"type" : "string",
|
||||
"description" : "The analyzer to use for the query string"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"methods": ["POST"],
|
||||
"url": {
|
||||
"path": "/{index}/{type}/{id}/_update",
|
||||
"paths": ["/{index}/{type}/{id}/_update"],
|
||||
"paths": ["/{index}/{type}/{id}/_update", "/{index}/_doc/{id}/_update"],
|
||||
"parts": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
|
@ -18,11 +18,14 @@
|
|||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"description": "The type of the document"
|
||||
}
|
||||
},
|
||||
"params": {
|
||||
"include_type_name": {
|
||||
"type" : "string",
|
||||
"description" : "Whether to add the type name to the response"
|
||||
},
|
||||
"wait_for_active_shards": {
|
||||
"type": "string",
|
||||
"description": "Sets the number of shard copies that must be active before proceeding with the update operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1)"
|
||||
|
|
|
@ -39,44 +39,257 @@
|
|||
- match: { index.mappings.properties.foo.type: "keyword" }
|
||||
- match: { index.mappings.properties.bar.type: "float" }
|
||||
|
||||
# Explicit id
|
||||
---
|
||||
"Index explicit IDs 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
|
||||
|
||||
- do:
|
||||
index:
|
||||
include_type_name: false
|
||||
index: index
|
||||
id: 1
|
||||
body: { foo: bar }
|
||||
|
||||
# Implicit id
|
||||
- do:
|
||||
index:
|
||||
index: index
|
||||
body: { foo: bar }
|
||||
- match: { "_index": "index" }
|
||||
- is_false: _type
|
||||
|
||||
# Bulk with explicit id
|
||||
- do:
|
||||
bulk:
|
||||
index: index
|
||||
include_type_name: false
|
||||
body: |
|
||||
{ "index": { "_id": "2" } }
|
||||
{ "doc": { "foo": "baz" } }
|
||||
|
||||
# Bulk with implicit id
|
||||
- match: { "items.0.index._index": "index" }
|
||||
- is_false: items.0.index._type
|
||||
|
||||
---
|
||||
"Index implicit IDs 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
|
||||
|
||||
- do:
|
||||
index:
|
||||
index: index
|
||||
include_type_name: false
|
||||
body: { foo: bar }
|
||||
|
||||
- match: { "_index": "index" }
|
||||
- is_false: _type
|
||||
|
||||
- do:
|
||||
bulk:
|
||||
index: index
|
||||
include_type_name: false
|
||||
body: |
|
||||
{ "index": { } }
|
||||
{ "doc": { "foo": "baz" } }
|
||||
|
||||
- match: { "items.0.index._index": "index" }
|
||||
- is_false: items.0.index._type
|
||||
|
||||
---
|
||||
"Mixing include_type_name=false with explicit 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
|
||||
|
||||
- do:
|
||||
catch: /illegal_argument_exception/
|
||||
index:
|
||||
index: index
|
||||
type: type
|
||||
id: 1
|
||||
include_type_name: false
|
||||
body: { foo: bar }
|
||||
|
||||
- do:
|
||||
catch: /illegal_argument_exception/
|
||||
index:
|
||||
index: index
|
||||
type: type
|
||||
include_type_name: false
|
||||
body: { foo: bar }
|
||||
|
||||
- do:
|
||||
catch: /illegal_argument_exception/
|
||||
get:
|
||||
index: index
|
||||
type: type
|
||||
id: 1
|
||||
include_type_name: false
|
||||
|
||||
- do:
|
||||
catch: /illegal_argument_exception/
|
||||
update:
|
||||
index: index
|
||||
type: type
|
||||
id: 1
|
||||
include_type_name: false
|
||||
body:
|
||||
doc: { foo: baz }
|
||||
|
||||
- do:
|
||||
catch: /illegal_argument_exception/
|
||||
delete:
|
||||
index: index
|
||||
type: type
|
||||
id: 1
|
||||
include_type_name: false
|
||||
|
||||
- do:
|
||||
catch: /illegal_argument_exception/
|
||||
search:
|
||||
index: index
|
||||
type: type
|
||||
include_type_name: false
|
||||
|
||||
- do:
|
||||
catch: /illegal_argument_exception/
|
||||
search:
|
||||
index: index
|
||||
type: _doc
|
||||
include_type_name: false
|
||||
|
||||
---
|
||||
"Update API 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
|
||||
|
||||
- do:
|
||||
index:
|
||||
index: index
|
||||
id: 1
|
||||
include_type_name: false
|
||||
body: { "foo": "bar" }
|
||||
|
||||
- do:
|
||||
update:
|
||||
index: index
|
||||
id: 1
|
||||
include_type_name: false
|
||||
body:
|
||||
doc: { "foo": "baz" }
|
||||
|
||||
- match: { "_index": "index" }
|
||||
- is_false: _type
|
||||
|
||||
---
|
||||
"GET API 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
|
||||
|
||||
- do:
|
||||
index:
|
||||
index: index
|
||||
id: 1
|
||||
include_type_name: false
|
||||
body: { "foo": "bar" }
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: index
|
||||
id: 1
|
||||
include_type_name: false
|
||||
|
||||
- match: { "_index": "index" }
|
||||
- is_false: _type
|
||||
|
||||
---
|
||||
"Delete API 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
|
||||
|
||||
- do:
|
||||
index:
|
||||
index: index
|
||||
id: 1
|
||||
include_type_name: false
|
||||
body: { "foo": "bar" }
|
||||
|
||||
- do:
|
||||
delete:
|
||||
index: index
|
||||
id: 1
|
||||
include_type_name: false
|
||||
|
||||
- match: { "_index": "index" }
|
||||
- is_false: _type
|
||||
|
||||
---
|
||||
"Search 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
|
||||
|
||||
- do:
|
||||
index:
|
||||
index: index
|
||||
id: 1
|
||||
include_type_name: false
|
||||
body: { "foo": "bar" }
|
||||
|
||||
- do:
|
||||
indices.refresh:
|
||||
index: index
|
||||
|
||||
- do:
|
||||
count:
|
||||
index: index
|
||||
|
||||
- match: { count: 4 }
|
||||
- do:
|
||||
search:
|
||||
index: index
|
||||
include_type_name: false
|
||||
|
||||
- match: { "hits.total": 1 }
|
||||
- match: { "hits.hits.0._index": "index" }
|
||||
- is_false: hits.hits.0._type
|
||||
|
||||
---
|
||||
"PUT mapping with a type and include_type_name: false":
|
||||
|
@ -88,6 +301,7 @@
|
|||
- do:
|
||||
indices.create:
|
||||
index: index
|
||||
include_type_name: false
|
||||
|
||||
- do:
|
||||
catch: /illegal_argument_exception/
|
||||
|
@ -101,7 +315,7 @@
|
|||
type: float
|
||||
|
||||
---
|
||||
"Empty index with the include_type_name=false option":
|
||||
"GET mappings on empty index with the include_type_name=false option":
|
||||
|
||||
- skip:
|
||||
version: " - 6.99.99"
|
||||
|
|
|
@ -295,9 +295,11 @@ public abstract class DocWriteResponse extends ReplicationResponse implements Wr
|
|||
|
||||
public XContentBuilder innerToXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
ReplicationResponse.ShardInfo shardInfo = getShardInfo();
|
||||
builder.field(_INDEX, shardId.getIndexName())
|
||||
.field(_TYPE, type)
|
||||
.field(_ID, id)
|
||||
builder.field(_INDEX, shardId.getIndexName());
|
||||
if (params.paramAsBoolean("include_type_name", true)) {
|
||||
builder.field(_TYPE, type);
|
||||
}
|
||||
builder.field(_ID, id)
|
||||
.field(_VERSION, version)
|
||||
.field(RESULT, getResult().getLowercase());
|
||||
if (forcedRefresh) {
|
||||
|
|
|
@ -252,7 +252,9 @@ public class GetResult implements Streamable, Iterable<DocumentField>, ToXConten
|
|||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
builder.field(_INDEX, index);
|
||||
builder.field(_TYPE, type);
|
||||
if (params.paramAsBoolean("include_type_name", true)) {
|
||||
builder.field(_TYPE, type);
|
||||
}
|
||||
builder.field(_ID, id);
|
||||
if (isExists()) {
|
||||
if (version != -1) {
|
||||
|
|
|
@ -72,7 +72,15 @@ public class RestBulkAction extends BaseRestHandler {
|
|||
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
|
||||
BulkRequest bulkRequest = Requests.bulkRequest();
|
||||
String defaultIndex = request.param("index");
|
||||
String defaultType = request.param("type", MapperService.SINGLE_MAPPING_NAME);
|
||||
String defaultType = request.param("type");
|
||||
final boolean includeTypeName = request.paramAsBoolean("include_type_name", true);
|
||||
if (includeTypeName == false && defaultType != null) {
|
||||
throw new IllegalArgumentException("You may only use the [include_type_name=false] option with the bulx APIs with the " +
|
||||
"[_bulk] and [{index}/_bulk] endpoints.");
|
||||
}
|
||||
if (defaultType == null) {
|
||||
defaultType = MapperService.SINGLE_MAPPING_NAME;
|
||||
}
|
||||
String defaultRouting = request.param("routing");
|
||||
FetchSourceContext defaultFetchSourceContext = FetchSourceContext.parseFromRestRequest(request);
|
||||
String defaultPipeline = request.param("pipeline");
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.elasticsearch.action.support.ActiveShardCount;
|
|||
import org.elasticsearch.client.node.NodeClient;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.VersionType;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.rest.BaseRestHandler;
|
||||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
|
@ -47,7 +48,13 @@ public class RestDeleteAction extends BaseRestHandler {
|
|||
|
||||
@Override
|
||||
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
|
||||
DeleteRequest deleteRequest = new DeleteRequest(request.param("index"), request.param("type"), request.param("id"));
|
||||
final boolean includeTypeName = request.paramAsBoolean("include_type_name", true);
|
||||
final String type = request.param("type");
|
||||
if (includeTypeName == false && MapperService.SINGLE_MAPPING_NAME.equals(type) == false) {
|
||||
throw new IllegalArgumentException("You may only use the [include_type_name=false] option with the delete API with the " +
|
||||
"[{index}/_doc/{id}] endpoints.");
|
||||
}
|
||||
DeleteRequest deleteRequest = new DeleteRequest(request.param("index"), type, request.param("id"));
|
||||
deleteRequest.routing(request.param("routing"));
|
||||
deleteRequest.timeout(request.paramAsTime("timeout", DeleteRequest.DEFAULT_TIMEOUT));
|
||||
deleteRequest.setRefreshPolicy(request.param("refresh"));
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.elasticsearch.client.node.NodeClient;
|
|||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.VersionType;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.rest.BaseRestHandler;
|
||||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
|
@ -55,7 +56,13 @@ public class RestGetAction extends BaseRestHandler {
|
|||
|
||||
@Override
|
||||
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
|
||||
final GetRequest getRequest = new GetRequest(request.param("index"), request.param("type"), request.param("id"));
|
||||
final boolean includeTypeName = request.paramAsBoolean("include_type_name", true);
|
||||
final String type = request.param("type");
|
||||
if (includeTypeName == false && MapperService.SINGLE_MAPPING_NAME.equals(type) == false) {
|
||||
throw new IllegalArgumentException("You may only use the [include_type_name=false] option with the get APIs with the " +
|
||||
"[{index}/_doc/{id}] endpoint.");
|
||||
}
|
||||
final GetRequest getRequest = new GetRequest(request.param("index"), type, request.param("id"));
|
||||
getRequest.refresh(request.paramAsBoolean("refresh", getRequest.refresh()));
|
||||
getRequest.routing(request.param("routing"));
|
||||
getRequest.preference(request.param("preference"));
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.elasticsearch.action.support.ActiveShardCount;
|
|||
import org.elasticsearch.client.node.NodeClient;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.VersionType;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.rest.BaseRestHandler;
|
||||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
|
@ -78,7 +79,13 @@ public class RestIndexAction extends BaseRestHandler {
|
|||
|
||||
@Override
|
||||
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
|
||||
IndexRequest indexRequest = new IndexRequest(request.param("index"), request.param("type"), request.param("id"));
|
||||
final boolean includeTypeName = request.paramAsBoolean("include_type_name", true);
|
||||
final String type = request.param("type");
|
||||
if (includeTypeName == false && MapperService.SINGLE_MAPPING_NAME.equals(type) == false) {
|
||||
throw new IllegalArgumentException("You may only use the [include_type_name=false] option with the index APIs with the " +
|
||||
"[{index}/_doc/{id}] and [{index}/_doc] endpoints.");
|
||||
}
|
||||
IndexRequest indexRequest = new IndexRequest(request.param("index"), type, request.param("id"));
|
||||
indexRequest.routing(request.param("routing"));
|
||||
indexRequest.setPipeline(request.param("pipeline"));
|
||||
indexRequest.source(request.requiredContent(), request.getXContentType());
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.elasticsearch.action.update.UpdateRequest;
|
|||
import org.elasticsearch.client.node.NodeClient;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.VersionType;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.rest.BaseRestHandler;
|
||||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
|
@ -50,7 +51,13 @@ public class RestUpdateAction extends BaseRestHandler {
|
|||
|
||||
@Override
|
||||
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
|
||||
UpdateRequest updateRequest = new UpdateRequest(request.param("index"), request.param("type"), request.param("id"));
|
||||
final boolean includeTypeName = request.paramAsBoolean("include_type_name", true);
|
||||
final String type = request.param("type");
|
||||
if (includeTypeName == false && MapperService.SINGLE_MAPPING_NAME.equals(type) == false) {
|
||||
throw new IllegalArgumentException("You may only use the [include_type_name=false] option with the update API with the " +
|
||||
"[{index}/_doc/{id}/_update] endpoint.");
|
||||
}
|
||||
UpdateRequest updateRequest = new UpdateRequest(request.param("index"), type, request.param("id"));
|
||||
updateRequest.routing(request.param("routing"));
|
||||
updateRequest.timeout(request.paramAsTime("timeout", updateRequest.timeout()));
|
||||
updateRequest.setRefreshPolicy(request.param("refresh"));
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.elasticsearch.common.logging.DeprecationLogger;
|
|||
import org.elasticsearch.common.logging.Loggers;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.rest.BaseRestHandler;
|
||||
import org.elasticsearch.rest.RestController;
|
||||
|
@ -150,8 +151,13 @@ public class RestSearchAction extends BaseRestHandler {
|
|||
searchRequest.scroll(new Scroll(parseTimeValue(scroll, null, "scroll")));
|
||||
}
|
||||
|
||||
final boolean includeTypeName = request.paramAsBoolean("include_type_name", true);
|
||||
String types = request.param("type");
|
||||
if (types != null) {
|
||||
if (includeTypeName == false) {
|
||||
throw new IllegalArgumentException("You may only use the [include_type_name=false] option with the search API with the " +
|
||||
"[{index}/_search] endpoint.");
|
||||
}
|
||||
DEPRECATION_LOGGER.deprecated("The {index}/{type}/_search endpoint is deprecated, use {index}/_search instead");
|
||||
}
|
||||
searchRequest.types(Strings.splitStringByCommaToArray(types));
|
||||
|
|
|
@ -426,7 +426,7 @@ public final class SearchHit implements Streamable, ToXContentObject, Iterable<D
|
|||
if (index != null) {
|
||||
builder.field(Fields._INDEX, RemoteClusterAware.buildRemoteIndexName(clusterAlias, index));
|
||||
}
|
||||
if (type != null) {
|
||||
if (type != null && params.paramAsBoolean("include_type_name", true)) {
|
||||
builder.field(Fields._TYPE, type);
|
||||
}
|
||||
if (id != null) {
|
||||
|
|
Loading…
Reference in New Issue