Skip to content

Commit

Permalink
add PUT options for _mapping
Browse files Browse the repository at this point in the history
Single type can now be added with

`[PUT|POST] {index|_all|*|regex|blank}/[_mapping|_mappings]/type`

and

`[PUT|POST] {index|_all|*|regex|blank}/type/[_mapping|_mappings]`

see roadmap at issue elastic#4071
  • Loading branch information
brwe committed Jan 13, 2014
1 parent 6be2066 commit fcea5e0
Show file tree
Hide file tree
Showing 5 changed files with 264 additions and 6 deletions.
22 changes: 22 additions & 0 deletions docs/reference/indices/put-mapping.asciidoc
Expand Up @@ -59,3 +59,25 @@ $ curl -XPUT 'http://localhost:9200/kimchy,elasticsearch/tweet/_mapping' -d '
}
'
--------------------------------------------------

All options:

[source,js]
--------------------------------------------------
[PUT|POST] /{index}/_mapping/{type}
[PUT|POST] /{index}/{type}/_mapping
--------------------------------------------------


where

[horizontal]
`{index}`:: `blank | * | _all | glob pattern | name1, name2, …`

`{type}`:: Name of the type to add. Must be the name of the type defined in the body.


Instead of `_mapping` you can also use the plural `_mappings`.
4 changes: 2 additions & 2 deletions rest-api-spec/api/indices.put_mapping.json
Expand Up @@ -4,11 +4,11 @@
"methods": ["PUT", "POST"],
"url": {
"path": "/{index}/{type}/_mapping",
"paths": ["/{index}/{type}/_mapping"],
"paths": ["/{index}/{type}/_mapping", "/{type}/_mapping", "/{index}/_mapping/{type}", "/_mapping/{type}", "/{index}/{type}/_mappings", "/{type}/_mappings", "/{index}/_mappings/{type}", "/_mappings/{type}"],
"parts": {
"index": {
"type" : "list",
"required" : true,
"required" : false,
"description" : "A comma-separated list of index names; use `_all` to perform the operation on all indices"
},
"type": {
Expand Down
184 changes: 184 additions & 0 deletions rest-api-spec/test/indices.put_mapping/all_path_options.yaml
@@ -0,0 +1,184 @@
---
"Test Create and update mapping with all options (PUT {index|_all|*|prefix*}/type/_mapping)":

# create two indices
- do:
indices.create:
index: test_index1
- do:
indices.create:
index: test_index2

# put mapping per index
- do:
indices.put_mapping:
index: test_index1
type: test_type
body:
test_type:
properties:
text:
type: string
analyzer: whitespace
- do:
indices.put_mapping:
index: test_index2
type: test_type
body:
test_type:
properties:
text:
type: string
analyzer: whitespace


- do:
indices.get_mapping:
index: test_index1

- match: {test_index1.test_type.properties.text.type: string}
- match: {test_index1.test_type.properties.text.analyzer: whitespace}

- do:
indices.get_mapping:
index: test_index2

- match: {test_index2.test_type.properties.text.type: string}
- match: {test_index2.test_type.properties.text.analyzer: whitespace}



# put mapping in _all index
- do:
indices.put_mapping:
index: _all
type: test_type1
body:
test_type1:
properties:
text:
type: string
analyzer: whitespace

- do:
indices.get_mapping:
index: test_index1

- match: {test_index1.test_type1.properties.text.type: string}
- match: {test_index1.test_type1.properties.text.analyzer: whitespace}

- do:
indices.get_mapping:
index: test_index2

- match: {test_index2.test_type1.properties.text.type: string}
- match: {test_index2.test_type1.properties.text.analyzer: whitespace}


# put mapping in * index
- do:
indices.put_mapping:
index: "*"
type: test_type2
body:
test_type2:
properties:
text:
type: string
analyzer: whitespace

- do:
indices.get_mapping:
index: test_index1

- match: {test_index1.test_type2.properties.text.type: string}
- match: {test_index1.test_type2.properties.text.analyzer: whitespace}

- do:
indices.get_mapping:
index: test_index2

- match: {test_index2.test_type2.properties.text.type: string}
- match: {test_index2.test_type2.properties.text.analyzer: whitespace}

# put mapping prefix* index
- do:
indices.put_mapping:
index: "test_index*"
type: test_type3
body:
test_type3:
properties:
text:
type: string
analyzer: whitespace

- do:
indices.get_mapping:
index: test_index1

- match: {test_index1.test_type3.properties.text.type: string}
- match: {test_index1.test_type3.properties.text.analyzer: whitespace}

- do:
indices.get_mapping:
index: test_index2

- match: {test_index2.test_type3.properties.text.type: string}
- match: {test_index2.test_type3.properties.text.analyzer: whitespace}



# put mapping in list of indices
- do:
indices.put_mapping:
index: [test_index1, test_index2]
type: test_type4
body:
test_type4:
properties:
text:
type: string
analyzer: whitespace

- do:
indices.get_mapping:
index: test_index1

- match: {test_index1.test_type4.properties.text.type: string}
- match: {test_index1.test_type4.properties.text.analyzer: whitespace}

- do:
indices.get_mapping:
index: test_index2

- match: {test_index2.test_type4.properties.text.type: string}
- match: {test_index2.test_type4.properties.text.analyzer: whitespace}


# put mapping with blank index
- do:
indices.put_mapping:
type: test_type5
body:
test_type5:
properties:
text:
type: string
analyzer: whitespace

- do:
indices.get_mapping:
index: test_index1

- match: {test_index1.test_type5.properties.text.type: string}
- match: {test_index1.test_type5.properties.text.analyzer: whitespace}

- do:
indices.get_mapping:
index: test_index2

- match: {test_index2.test_type5.properties.text.type: string}
- match: {test_index2.test_type5.properties.text.analyzer: whitespace}


Expand Up @@ -37,14 +37,60 @@
*/
public class RestPutMappingAction extends BaseRestHandler {

/*
* This TestHandler is a workaround. With the current path registration
* (PathTrie) registering /{type}/_mapping in order to leave the index
* blank, the first parameter in the path will still map to "index". * In
* order to register /{type}/_mapping as path, we instead register
* /{index}/_mapping and interpret the parameter "index" as type if no type
* is given in the uri parameters.
*/
protected final class RestHandlerForMissingIndex implements RestHandler {
@Override
public void handleRequest(RestRequest request, RestChannel channel) {
PutMappingRequest putMappingRequest;
if (request.param("type") != null) {
putMappingRequest = putMappingRequest(Strings.splitStringByCommaToArray(request.param("index")));
putMappingRequest.type(request.param("type"));
} else {
putMappingRequest = putMappingRequest(new String[0]);
putMappingRequest.type(request.param("index"));
}
putMappingRequest.listenerThreaded(false);
putMappingRequest.source(request.content().toUtf8());
putMappingRequest.timeout(request.paramAsTime("timeout", putMappingRequest.timeout()));
putMappingRequest.ignoreConflicts(request.paramAsBoolean("ignore_conflicts", putMappingRequest.ignoreConflicts()));
putMappingRequest.masterNodeTimeout(request.paramAsTime("master_timeout", putMappingRequest.masterNodeTimeout()));
putMappingRequest.indicesOptions(IndicesOptions.fromRequest(request, putMappingRequest.indicesOptions()));
client.admin()
.indices()
.putMapping(putMappingRequest, new AcknowledgedRestResponseActionListener<PutMappingResponse>(request, channel, logger));
}
}

@Inject
public RestPutMappingAction(Settings settings, Client client, RestController controller) {
super(settings, client);
controller.registerHandler(PUT, "/{index}/_mapping", this);
controller.registerHandler(PUT, "/{index}/_mapping/", new RestHandlerForMissingIndex());
controller.registerHandler(PUT, "/{index}/{type}/_mapping", this);
controller.registerHandler(PUT, "/{index}/_mapping/{type}", this);
controller.registerHandler(PUT, "/_mapping/{type}", this);

controller.registerHandler(POST, "/{index}/_mapping", this);
controller.registerHandler(POST, "/{index}/_mapping/", new RestHandlerForMissingIndex());
controller.registerHandler(POST, "/{index}/{type}/_mapping", this);
controller.registerHandler(POST, "/{index}/_mapping/{type}", this);
controller.registerHandler(POST, "/_mapping/{type}", this);

//register the same paths, but with plural form _mappings
controller.registerHandler(PUT, "/{index}/_mappings/", new RestHandlerForMissingIndex());
controller.registerHandler(PUT, "/{index}/{type}/_mappings", this);
controller.registerHandler(PUT, "/{index}/_mappings/{type}", this);
controller.registerHandler(PUT, "/_mappings/{type}", this);

controller.registerHandler(POST, "/{index}/_mappings/", new RestHandlerForMissingIndex());
controller.registerHandler(POST, "/{index}/{type}/_mappings", this);
controller.registerHandler(POST, "/{index}/_mappings/{type}", this);
controller.registerHandler(POST, "/_mappings/{type}", this);
}

@Override
Expand Down
10 changes: 8 additions & 2 deletions src/test/java/org/elasticsearch/indices/IndicesOptionsTests.java
Expand Up @@ -623,12 +623,18 @@ public void testPutMapping() throws Exception {
assertThat(client().admin().indices().prepareGetMappings("foobar").get().mappings().get("foobar").get("type2"), notNullValue());
assertThat(client().admin().indices().prepareGetMappings("bar").get().mappings().get("bar").get("type2"), notNullValue());
assertThat(client().admin().indices().prepareGetMappings("barbaz").get().mappings().get("barbaz").get("type2"), notNullValue());
verify(client().admin().indices().preparePutMapping().setType("type3").setSource("field", "type=string"), false);
assertThat(client().admin().indices().prepareGetMappings("foo").get().mappings().get("foo").get("type3"), notNullValue());
assertThat(client().admin().indices().prepareGetMappings("foobar").get().mappings().get("foobar").get("type3"), notNullValue());
assertThat(client().admin().indices().prepareGetMappings("bar").get().mappings().get("bar").get("type3"), notNullValue());
assertThat(client().admin().indices().prepareGetMappings("barbaz").get().mappings().get("barbaz").get("type3"), notNullValue());


verify(client().admin().indices().preparePutMapping("c*").setType("type1").setSource("field", "type=string"), true);

assertAcked(client().admin().indices().prepareClose("barbaz").get());
verify(client().admin().indices().preparePutMapping("barbaz").setType("type3").setSource("field", "type=string"), false);
assertThat(client().admin().indices().prepareGetMappings("barbaz").get().mappings().get("barbaz").get("type3"), notNullValue());
verify(client().admin().indices().preparePutMapping("barbaz").setType("type4").setSource("field", "type=string"), false);
assertThat(client().admin().indices().prepareGetMappings("barbaz").get().mappings().get("barbaz").get("type4"), notNullValue());
}

@Test
Expand Down

0 comments on commit fcea5e0

Please sign in to comment.