Fix put mappings java API documentation (#31955)

The current docs of the put-mapping Java API is currently broken. It its current
form, it creates an index and uses the whole mapping definition given as a JSON
string as the type name. Since we didn't check the index created in the
IndicesDocumentationIT so far this went unnoticed.

This change adds test to catch this error to the documentation test, changes the
documentation so it works correctly now and adds an input validation to
PutMappingRequest#buildFromSimplifiedDef() which was used internally to reject
calls where no mapping definition is given.

Closes #31906
This commit is contained in:
Christoph Büscher 2018-07-17 09:09:03 +02:00 committed by GitHub
parent 61486680a2
commit 36165265ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 47 additions and 16 deletions

View File

@ -2,17 +2,22 @@
==== Put Mapping
The PUT mapping API allows you to add a new type while creating an index:
You can add mappings for a new type at index creation time:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{client-tests}/IndicesDocumentationIT.java[index-with-mapping]
--------------------------------------------------
<1> <<java-admin-indices-create-index,Creates an index>> called `twitter`
<2> It also adds a `tweet` mapping type.
<2> Add a `tweet` type with a field called `message` that has the datatype `text`.
There are several variants of the above `addMapping` method, some taking an
`XContentBuilder` or a `Map` with the mapping definition as arguments. Make sure
to check the javadocs to pick the simplest one for your use case.
The PUT mapping API also allows to add a new type to an existing index:
The PUT mapping API also allows to specify the mapping of a type after index
creation. In this case you can provide the mapping as a String similar to the
Rest API syntax:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------

View File

@ -184,10 +184,13 @@ public class PutMappingRequest extends AcknowledgedRequest<PutMappingRequest> im
}
/**
* @param type the mapping type
* @param source consisting of field/properties pairs (e.g. "field1",
* "type=string,store=true"). If the number of arguments is not
* divisible by two an {@link IllegalArgumentException} is thrown
* @param type
* the mapping type
* @param source
* consisting of field/properties pairs (e.g. "field1",
* "type=string,store=true")
* @throws IllegalArgumentException
* if the number of the source arguments is not divisible by two
* @return the mappings definition
*/
public static XContentBuilder buildFromSimplifiedDef(String type, Object... source) {

View File

@ -76,8 +76,12 @@ public class PutMappingRequestTests extends ESTestCase {
" concrete index: [[foo/bar]] and indices: [myindex];");
}
/**
* Test that {@link PutMappingRequest#buildFromSimplifiedDef(String, Object...)}
* rejects inputs where the {@code Object...} varargs of field name and properties are not
* paired correctly
*/
public void testBuildFromSimplifiedDef() {
// test that method rejects input where input varargs fieldname/properites are not paired correctly
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
() -> PutMappingRequest.buildFromSimplifiedDef("type", "only_field"));
assertEquals("mapping source must be pairs of fieldnames and properties definition.", e.getMessage());

View File

@ -19,10 +19,19 @@
package org.elasticsearch.client.documentation;
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.test.ESIntegTestCase;
import java.util.HashMap;
import java.util.Map;
import static java.util.Collections.singletonMap;
import static org.hamcrest.Matchers.instanceOf;
/**
* This class is used to generate the Java indices administration documentation.
* You need to wrap your code between two tags like:
@ -48,16 +57,14 @@ public class IndicesDocumentationIT extends ESIntegTestCase {
Client client = client();
// tag::index-with-mapping
client.admin().indices().prepareCreate("twitter") // <1>
.addMapping("\"tweet\": {\n" + // <2>
" \"properties\": {\n" +
" \"message\": {\n" +
" \"type\": \"text\"\n" +
" }\n" +
" }\n" +
"}")
client.admin().indices().prepareCreate("twitter") // <1>
.addMapping("tweet", "message", "type=text") // <2>
.get();
// end::index-with-mapping
GetMappingsResponse getMappingsResponse = client.admin().indices().prepareGetMappings("twitter").get();
assertEquals(1, getMappingsResponse.getMappings().size());
ImmutableOpenMap<String, MappingMetaData> indexMapping = getMappingsResponse.getMappings().get("twitter");
assertThat(indexMapping.get("tweet"), instanceOf(MappingMetaData.class));
// we need to delete in order to create a fresh new index with another type
client.admin().indices().prepareDelete("twitter").get();
@ -89,6 +96,11 @@ public class IndicesDocumentationIT extends ESIntegTestCase {
"}", XContentType.JSON)
.get();
// end::putMapping-request-source
getMappingsResponse = client.admin().indices().prepareGetMappings("twitter").get();
assertEquals(1, getMappingsResponse.getMappings().size());
indexMapping = getMappingsResponse.getMappings().get("twitter");
assertEquals(singletonMap("properties", singletonMap("name", singletonMap("type", "text"))),
indexMapping.get("user").getSourceAsMap());
// tag::putMapping-request-source-append
client.admin().indices().preparePutMapping("twitter") // <1>
@ -102,6 +114,13 @@ public class IndicesDocumentationIT extends ESIntegTestCase {
"}", XContentType.JSON)
.get();
// end::putMapping-request-source-append
getMappingsResponse = client.admin().indices().prepareGetMappings("twitter").get();
assertEquals(1, getMappingsResponse.getMappings().size());
indexMapping = getMappingsResponse.getMappings().get("twitter");
Map<String, Map<?,?>> expected = new HashMap<>();
expected.put("name", singletonMap("type", "text"));
expected.put("user_name", singletonMap("type", "text"));
assertEquals(expected, indexMapping.get("user").getSourceAsMap().get("properties"));
}
}