Mappings: Remove ability to set path for _id and _routing on 2.0+ indexes

_id and _routing now no longer support the 'path' setting on indexes
created with 2.0.  Indexes created before 2.0 still support this
setting for backcompat.

closes #6730
This commit is contained in:
Ryan Ernst 2015-02-09 21:50:55 -08:00
parent 6544890e14
commit b3474f6b25
15 changed files with 106 additions and 134 deletions

View File

@ -175,6 +175,15 @@ def generate_index(client, version):
} }
} }
} }
mappings['meta_fields'] = {
'_id': {
'path': 'myid'
},
'_routing': {
'path': 'myrouting'
}
}
client.indices.create(index='test', body={ client.indices.create(index='test', body={
'settings': { 'settings': {

View File

@ -25,31 +25,3 @@ using the appropriate mapping attributes:
} }
-------------------------------------------------- --------------------------------------------------
The `_id` mapping can also be associated with a `path` that will be used
to extract the id from a different location in the source document. For
example, having the following mapping:
[source,js]
--------------------------------------------------
{
"tweet" : {
"_id" : {
"path" : "post_id"
}
}
}
--------------------------------------------------
Will cause `1` to be used as the id for:
[source,js]
--------------------------------------------------
{
"message" : "You know, for Search",
"post_id" : "1"
}
--------------------------------------------------
This does require an additional lightweight parsing step while indexing,
in order to extract the id to decide which shard the index operation
will be executed on.

View File

@ -24,42 +24,6 @@ has been provided (or derived from the doc). A delete operation will be
broadcasted to all shards if no routing value is provided and `_routing` broadcasted to all shards if no routing value is provided and `_routing`
is required. is required.
[float]
==== path
The routing value can be provided as an external value when indexing
(and still stored as part of the document, in much the same way
`_source` is stored). But, it can also be automatically extracted from
the index doc based on a `path`. For example, having the following
mapping:
[source,js]
--------------------------------------------------
{
"comment" : {
"_routing" : {
"required" : true,
"path" : "blog.post_id"
}
}
}
--------------------------------------------------
Will cause the following doc to be routed based on the `111222` value:
[source,js]
--------------------------------------------------
{
"text" : "the comment text"
"blog" : {
"post_id" : "111222"
}
}
--------------------------------------------------
Note, using `path` without explicit routing value provided required an
additional (though quite fast) parsing phase.
[float] [float]
==== id uniqueness ==== id uniqueness

View File

@ -183,19 +183,11 @@ public class DocumentMapper implements ToXContent {
this.indexSettings = indexSettings; this.indexSettings = indexSettings;
this.builderContext = new Mapper.BuilderContext(indexSettings, new ContentPath(1)); this.builderContext = new Mapper.BuilderContext(indexSettings, new ContentPath(1));
this.rootObjectMapper = builder.build(builderContext); this.rootObjectMapper = builder.build(builderContext);
IdFieldMapper idFieldMapper = new IdFieldMapper();
if (indexSettings != null) {
String idIndexed = indexSettings.get("index.mapping._id.indexed");
if (idIndexed != null && Booleans.parseBoolean(idIndexed, false)) {
FieldType fieldType = new FieldType(IdFieldMapper.Defaults.FIELD_TYPE);
fieldType.setTokenized(false);
idFieldMapper = new IdFieldMapper(fieldType);
}
}
// UID first so it will be the first stored field to load (so will benefit from "fields: []" early termination // UID first so it will be the first stored field to load (so will benefit from "fields: []" early termination
this.rootMappers.put(UidFieldMapper.class, new UidFieldMapper()); this.rootMappers.put(UidFieldMapper.class, new UidFieldMapper());
this.rootMappers.put(IdFieldMapper.class, idFieldMapper); this.rootMappers.put(IdFieldMapper.class, new IdFieldMapper(indexSettings));
this.rootMappers.put(RoutingFieldMapper.class, new RoutingFieldMapper()); this.rootMappers.put(RoutingFieldMapper.class, new RoutingFieldMapper(indexSettings));
// add default mappers, order is important (for example analyzer should come before the rest to set context.analyzer) // add default mappers, order is important (for example analyzer should come before the rest to set context.analyzer)
this.rootMappers.put(SizeFieldMapper.class, new SizeFieldMapper(indexSettings)); this.rootMappers.put(SizeFieldMapper.class, new SizeFieldMapper(indexSettings));
this.rootMappers.put(IndexFieldMapper.class, new IndexFieldMapper()); this.rootMappers.put(IndexFieldMapper.class, new IndexFieldMapper());

View File

@ -29,6 +29,7 @@ import org.apache.lucene.index.Term;
import org.apache.lucene.queries.TermsFilter; import org.apache.lucene.queries.TermsFilter;
import org.apache.lucene.search.*; import org.apache.lucene.search.*;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.elasticsearch.Version;
import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.lucene.BytesRefs; import org.elasticsearch.common.lucene.BytesRefs;
@ -58,7 +59,7 @@ import static org.elasticsearch.index.mapper.MapperBuilders.id;
import static org.elasticsearch.index.mapper.core.TypeParsers.parseField; import static org.elasticsearch.index.mapper.core.TypeParsers.parseField;
/** /**
* *
*/ */
public class IdFieldMapper extends AbstractFieldMapper<String> implements InternalMapper, RootMapper { public class IdFieldMapper extends AbstractFieldMapper<String> implements InternalMapper, RootMapper {
@ -115,7 +116,7 @@ public class IdFieldMapper extends AbstractFieldMapper<String> implements Intern
Map.Entry<String, Object> entry = iterator.next(); Map.Entry<String, Object> entry = iterator.next();
String fieldName = Strings.toUnderscoreCase(entry.getKey()); String fieldName = Strings.toUnderscoreCase(entry.getKey());
Object fieldNode = entry.getValue(); Object fieldNode = entry.getValue();
if (fieldName.equals("path")) { if (fieldName.equals("path") && parserContext.indexVersionCreated().before(Version.V_2_0_0)) {
builder.path(fieldNode.toString()); builder.path(fieldNode.toString());
iterator.remove(); iterator.remove();
} }
@ -125,17 +126,10 @@ public class IdFieldMapper extends AbstractFieldMapper<String> implements Intern
} }
private final String path; private final String path;
private final boolean writePre20Settings;
public IdFieldMapper() { public IdFieldMapper(Settings indexSettings) {
this(new FieldType(Defaults.FIELD_TYPE)); this(Defaults.NAME, Defaults.INDEX_NAME, Defaults.BOOST, idFieldType(indexSettings), null, Defaults.PATH, null, null, null, indexSettings);
}
public IdFieldMapper(FieldType fieldType) {
this(Defaults.NAME, Defaults.INDEX_NAME, fieldType, null);
}
protected IdFieldMapper(String name, String indexName, FieldType fieldType, Boolean docValues) {
this(name, indexName, Defaults.BOOST, fieldType, docValues, Defaults.PATH, null, null, null, ImmutableSettings.EMPTY);
} }
protected IdFieldMapper(String name, String indexName, float boost, FieldType fieldType, Boolean docValues, String path, protected IdFieldMapper(String name, String indexName, float boost, FieldType fieldType, Boolean docValues, String path,
@ -144,6 +138,15 @@ public class IdFieldMapper extends AbstractFieldMapper<String> implements Intern
super(new Names(name, indexName, indexName, name), boost, fieldType, docValues, Lucene.KEYWORD_ANALYZER, super(new Names(name, indexName, indexName, name), boost, fieldType, docValues, Lucene.KEYWORD_ANALYZER,
Lucene.KEYWORD_ANALYZER, postingsProvider, docValuesProvider, null, null, fieldDataSettings, indexSettings); Lucene.KEYWORD_ANALYZER, postingsProvider, docValuesProvider, null, null, fieldDataSettings, indexSettings);
this.path = path; this.path = path;
this.writePre20Settings = Version.indexCreated(indexSettings).before(Version.V_2_0_0);
}
private static FieldType idFieldType(Settings indexSettings) {
FieldType fieldType = new FieldType(Defaults.FIELD_TYPE);
if (indexSettings.getAsBoolean("index.mapping._id.indexed", true) == false) {
fieldType.setTokenized(false);
}
return fieldType;
} }
public String path() { public String path() {
@ -351,7 +354,7 @@ public class IdFieldMapper extends AbstractFieldMapper<String> implements Intern
if (includeDefaults || fieldType.indexOptions() != Defaults.FIELD_TYPE.indexOptions()) { if (includeDefaults || fieldType.indexOptions() != Defaults.FIELD_TYPE.indexOptions()) {
builder.field("index", indexTokenizeOptionToString(fieldType.indexOptions() != IndexOptions.NONE, fieldType.tokenized())); builder.field("index", indexTokenizeOptionToString(fieldType.indexOptions() != IndexOptions.NONE, fieldType.tokenized()));
} }
if (includeDefaults || path != Defaults.PATH) { if (writePre20Settings && (includeDefaults || path != Defaults.PATH)) {
builder.field("path", path); builder.field("path", path);
} }

View File

@ -23,6 +23,7 @@ import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType; import org.apache.lucene.document.FieldType;
import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexOptions;
import org.elasticsearch.Version;
import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.lucene.Lucene;
@ -107,7 +108,7 @@ public class RoutingFieldMapper extends AbstractFieldMapper<String> implements I
if (fieldName.equals("required")) { if (fieldName.equals("required")) {
builder.required(nodeBooleanValue(fieldNode)); builder.required(nodeBooleanValue(fieldNode));
iterator.remove(); iterator.remove();
} else if (fieldName.equals("path")) { } else if (fieldName.equals("path") && parserContext.indexVersionCreated().before(Version.V_2_0_0)) {
builder.path(fieldNode.toString()); builder.path(fieldNode.toString());
iterator.remove(); iterator.remove();
} }
@ -118,11 +119,11 @@ public class RoutingFieldMapper extends AbstractFieldMapper<String> implements I
private boolean required; private boolean required;
private final String path; private final String path;
private final boolean writePre20Settings;
public RoutingFieldMapper() { public RoutingFieldMapper(Settings indexSettings) {
this(new FieldType(Defaults.FIELD_TYPE), Defaults.REQUIRED, Defaults.PATH, null, null, null, ImmutableSettings.EMPTY); this(Defaults.FIELD_TYPE, Defaults.REQUIRED, Defaults.PATH, null, null, null, indexSettings);
} }
protected RoutingFieldMapper(FieldType fieldType, boolean required, String path, PostingsFormatProvider postingsProvider, protected RoutingFieldMapper(FieldType fieldType, boolean required, String path, PostingsFormatProvider postingsProvider,
@ -131,6 +132,7 @@ public class RoutingFieldMapper extends AbstractFieldMapper<String> implements I
Lucene.KEYWORD_ANALYZER, postingsProvider, docValuesProvider, null, null, fieldDataSettings, indexSettings); Lucene.KEYWORD_ANALYZER, postingsProvider, docValuesProvider, null, null, fieldDataSettings, indexSettings);
this.required = required; this.required = required;
this.path = path; this.path = path;
this.writePre20Settings = Version.indexCreated(indexSettings).before(Version.V_2_0_0);
} }
@Override @Override
@ -234,7 +236,7 @@ public class RoutingFieldMapper extends AbstractFieldMapper<String> implements I
if (includeDefaults || required != Defaults.REQUIRED) { if (includeDefaults || required != Defaults.REQUIRED) {
builder.field("required", required); builder.field("required", required);
} }
if (includeDefaults || path != Defaults.PATH) { if (writePre20Settings && (includeDefaults || path != Defaults.PATH)) {
builder.field("path", path); builder.field("path", path);
} }
builder.endObject(); builder.endObject();

View File

@ -21,6 +21,7 @@ package org.elasticsearch.document;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import org.elasticsearch.Version;
import org.elasticsearch.action.admin.indices.alias.Alias; import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkRequest;
@ -35,6 +36,7 @@ import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateRequestBuilder; import org.elasticsearch.action.update.UpdateRequestBuilder;
import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
@ -594,7 +596,8 @@ public class BulkTests extends ElasticsearchIntegrationTest {
.endObject() .endObject()
.endObject() .endObject()
.endObject(); .endObject();
assertAcked(prepareCreate("test").addMapping("type", builder)); assertAcked(prepareCreate("test").addMapping("type", builder)
.setSettings(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2_ID));
ensureYellow("test"); ensureYellow("test");
String brokenBuildRequestData = "{\"index\": {} }\n" + String brokenBuildRequestData = "{\"index\": {} }\n" +
@ -620,7 +623,8 @@ public class BulkTests extends ElasticsearchIntegrationTest {
.endObject() .endObject()
.endObject() .endObject()
.endObject(); .endObject();
assertAcked(prepareCreate("test").addMapping("type", builder)); assertAcked(prepareCreate("test").addMapping("type", builder)
.setSettings(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2_ID));
ensureYellow("test"); ensureYellow("test");
String brokenBuildRequestData = "{\"index\": {} }\n" + String brokenBuildRequestData = "{\"index\": {} }\n" +

View File

@ -19,6 +19,10 @@
package org.elasticsearch.index.mapper.id; package org.elasticsearch.index.mapper.id;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentFactory;
@ -28,15 +32,13 @@ import org.elasticsearch.index.mapper.ParsedDocument;
import org.elasticsearch.index.mapper.internal.IdFieldMapper; import org.elasticsearch.index.mapper.internal.IdFieldMapper;
import org.elasticsearch.index.mapper.internal.UidFieldMapper; import org.elasticsearch.index.mapper.internal.UidFieldMapper;
import org.elasticsearch.test.ElasticsearchSingleNodeTest; import org.elasticsearch.test.ElasticsearchSingleNodeTest;
import org.junit.Test;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
/**
*/
public class IdMappingTests extends ElasticsearchSingleNodeTest { public class IdMappingTests extends ElasticsearchSingleNodeTest {
@Test
public void simpleIdTests() throws Exception { public void simpleIdTests() throws Exception {
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type") String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.endObject().endObject().string(); .endObject().endObject().string();
@ -68,8 +70,7 @@ public class IdMappingTests extends ElasticsearchSingleNodeTest {
assertThat(doc.rootDoc().get(UidFieldMapper.NAME), notNullValue()); assertThat(doc.rootDoc().get(UidFieldMapper.NAME), notNullValue());
assertThat(doc.rootDoc().get(IdFieldMapper.NAME), nullValue()); assertThat(doc.rootDoc().get(IdFieldMapper.NAME), nullValue());
} }
@Test
public void testIdIndexed() throws Exception { public void testIdIndexed() throws Exception {
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type") String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("_id").field("index", "not_analyzed").endObject() .startObject("_id").field("index", "not_analyzed").endObject()
@ -93,13 +94,13 @@ public class IdMappingTests extends ElasticsearchSingleNodeTest {
assertThat(doc.rootDoc().get(UidFieldMapper.NAME), notNullValue()); assertThat(doc.rootDoc().get(UidFieldMapper.NAME), notNullValue());
assertThat(doc.rootDoc().get(IdFieldMapper.NAME), notNullValue()); assertThat(doc.rootDoc().get(IdFieldMapper.NAME), notNullValue());
} }
@Test
public void testIdPath() throws Exception { public void testIdPath() throws Exception {
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type") String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("_id").field("path", "my_path").endObject() .startObject("_id").field("path", "my_path").endObject()
.endObject().endObject().string(); .endObject().endObject().string();
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse(mapping); Settings settings = ImmutableSettings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2_ID).build();
DocumentMapper docMapper = createIndex("test", settings).mapperService().documentMapperParser().parse(mapping);
// serialize the id mapping // serialize the id mapping
XContentBuilder builder = XContentFactory.jsonBuilder().startObject(); XContentBuilder builder = XContentFactory.jsonBuilder().startObject();

View File

@ -61,13 +61,11 @@ public class RoutingTypeMapperTests extends ElasticsearchSingleNodeTest {
.startObject("_routing") .startObject("_routing")
.field("store", "no") .field("store", "no")
.field("index", "no") .field("index", "no")
.field("path", "route")
.endObject() .endObject()
.endObject().endObject().string(); .endObject().endObject().string();
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse(mapping); DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse(mapping);
assertThat(docMapper.routingFieldMapper().fieldType().stored(), equalTo(false)); assertThat(docMapper.routingFieldMapper().fieldType().stored(), equalTo(false));
assertEquals(IndexOptions.NONE, docMapper.routingFieldMapper().fieldType().indexOptions()); assertEquals(IndexOptions.NONE, docMapper.routingFieldMapper().fieldType().indexOptions());
assertThat(docMapper.routingFieldMapper().path(), equalTo("route"));
} }
@Test @Test

View File

@ -20,6 +20,7 @@
package org.elasticsearch.routing; package org.elasticsearch.routing;
import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.Version;
import org.elasticsearch.action.RoutingMissingException; import org.elasticsearch.action.RoutingMissingException;
import org.elasticsearch.action.admin.indices.alias.Alias; import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.explain.ExplainResponse; import org.elasticsearch.action.explain.ExplainResponse;
@ -30,6 +31,9 @@ import org.elasticsearch.action.termvectors.TermVectorsRequest;
import org.elasticsearch.action.termvectors.TermVectorsResponse; import org.elasticsearch.action.termvectors.TermVectorsResponse;
import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Requests; import org.elasticsearch.client.Requests;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.mapper.MapperParsingException; import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryBuilders;
@ -40,17 +44,13 @@ import org.junit.Test;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
/**
*
*/
public class SimpleRoutingTests extends ElasticsearchIntegrationTest { public class SimpleRoutingTests extends ElasticsearchIntegrationTest {
@Override @Override
protected int minimumNumberOfShards() { protected int minimumNumberOfShards() {
return 2; return 2;
} }
@Test
public void testSimpleCrudRouting() throws Exception { public void testSimpleCrudRouting() throws Exception {
createIndex("test"); createIndex("test");
ensureGreen(); ensureGreen();
@ -107,8 +107,7 @@ public class SimpleRoutingTests extends ElasticsearchIntegrationTest {
assertThat(client().prepareGet("test", "type1", "1").setRouting("0").execute().actionGet().isExists(), equalTo(false)); assertThat(client().prepareGet("test", "type1", "1").setRouting("0").execute().actionGet().isExists(), equalTo(false));
} }
} }
@Test
public void testSimpleSearchRouting() { public void testSimpleSearchRouting() {
createIndex("test"); createIndex("test");
ensureGreen(); ensureGreen();
@ -174,8 +173,7 @@ public class SimpleRoutingTests extends ElasticsearchIntegrationTest {
assertThat(client().prepareCount().setRouting("0", "1", "0").setQuery(QueryBuilders.matchAllQuery()).execute().actionGet().getCount(), equalTo(2l)); assertThat(client().prepareCount().setRouting("0", "1", "0").setQuery(QueryBuilders.matchAllQuery()).execute().actionGet().getCount(), equalTo(2l));
} }
} }
@Test
public void testRequiredRoutingMapping() throws Exception { public void testRequiredRoutingMapping() throws Exception {
client().admin().indices().prepareCreate("test").addAlias(new Alias("alias")) client().admin().indices().prepareCreate("test").addAlias(new Alias("alias"))
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("_routing").field("required", true).endObject().endObject().endObject()) .addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("_routing").field("required", true).endObject().endObject().endObject())
@ -230,8 +228,7 @@ public class SimpleRoutingTests extends ElasticsearchIntegrationTest {
assertThat(client().prepareGet(indexOrAlias(), "type1", "1").setRouting("0").execute().actionGet().isExists(), equalTo(false)); assertThat(client().prepareGet(indexOrAlias(), "type1", "1").setRouting("0").execute().actionGet().isExists(), equalTo(false));
} }
} }
@Test
public void testRequiredRoutingWithPathMapping() throws Exception { public void testRequiredRoutingWithPathMapping() throws Exception {
client().admin().indices().prepareCreate("test") client().admin().indices().prepareCreate("test")
.addAlias(new Alias("alias")) .addAlias(new Alias("alias"))
@ -239,6 +236,7 @@ public class SimpleRoutingTests extends ElasticsearchIntegrationTest {
.startObject("_routing").field("required", true).field("path", "routing_field").endObject().startObject("properties") .startObject("_routing").field("required", true).field("path", "routing_field").endObject().startObject("properties")
.startObject("routing_field").field("type", "string").field("index", randomBoolean() ? "no" : "not_analyzed").field("doc_values", randomBoolean() ? "yes" : "no").endObject().endObject() .startObject("routing_field").field("type", "string").field("index", randomBoolean() ? "no" : "not_analyzed").field("doc_values", randomBoolean() ? "yes" : "no").endObject().endObject()
.endObject().endObject()) .endObject().endObject())
.setSettings(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2_ID)
.execute().actionGet(); .execute().actionGet();
ensureGreen(); ensureGreen();
@ -269,14 +267,14 @@ public class SimpleRoutingTests extends ElasticsearchIntegrationTest {
assertThat(client().prepareGet(indexOrAlias(), "type1", "1").setRouting("0").execute().actionGet().isExists(), equalTo(true)); assertThat(client().prepareGet(indexOrAlias(), "type1", "1").setRouting("0").execute().actionGet().isExists(), equalTo(true));
} }
} }
@Test
public void testRequiredRoutingWithPathMappingBulk() throws Exception { public void testRequiredRoutingWithPathMappingBulk() throws Exception {
client().admin().indices().prepareCreate("test") client().admin().indices().prepareCreate("test")
.addAlias(new Alias("alias")) .addAlias(new Alias("alias"))
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1") .addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1")
.startObject("_routing").field("required", true).field("path", "routing_field").endObject() .startObject("_routing").field("required", true).field("path", "routing_field").endObject()
.endObject().endObject()) .endObject().endObject())
.setSettings(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2_ID)
.execute().actionGet(); .execute().actionGet();
ensureGreen(); ensureGreen();
@ -301,14 +299,44 @@ public class SimpleRoutingTests extends ElasticsearchIntegrationTest {
} }
} }
@Test public void testRequiredRoutingBulk() throws Exception {
public void testRequiredRoutingWithPathNumericType() throws Exception { client().admin().indices().prepareCreate("test")
.addAlias(new Alias("alias"))
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1")
.startObject("_routing").field("required", true).endObject()
.endObject().endObject())
.execute().actionGet();
ensureGreen();
logger.info("--> indexing with id [1], and routing [0]");
client().prepareBulk().add(
client().prepareIndex(indexOrAlias(), "type1", "1").setRouting("0").setSource("field", "value1")).execute().actionGet();
client().admin().indices().prepareRefresh().execute().actionGet();
logger.info("--> verifying get with no routing, should fail");
for (int i = 0; i < 5; i++) {
try {
client().prepareGet(indexOrAlias(), "type1", "1").execute().actionGet().isExists();
fail();
} catch (RoutingMissingException e) {
assertThat(e.status(), equalTo(RestStatus.BAD_REQUEST));
assertThat(e.getMessage(), equalTo("routing is required for [test]/[type1]/[1]"));
}
}
logger.info("--> verifying get with routing, should find");
for (int i = 0; i < 5; i++) {
assertThat(client().prepareGet(indexOrAlias(), "type1", "1").setRouting("0").execute().actionGet().isExists(), equalTo(true));
}
}
public void testRequiredRoutingWithPathNumericType() throws Exception {
client().admin().indices().prepareCreate("test") client().admin().indices().prepareCreate("test")
.addAlias(new Alias("alias")) .addAlias(new Alias("alias"))
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1") .addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1")
.startObject("_routing").field("required", true).field("path", "routing_field").endObject() .startObject("_routing").field("required", true).field("path", "routing_field").endObject()
.endObject().endObject()) .endObject().endObject())
.setSettings(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2_ID)
.execute().actionGet(); .execute().actionGet();
ensureGreen(); ensureGreen();
@ -331,8 +359,7 @@ public class SimpleRoutingTests extends ElasticsearchIntegrationTest {
assertThat(client().prepareGet(indexOrAlias(), "type1", "1").setRouting("0").execute().actionGet().isExists(), equalTo(true)); assertThat(client().prepareGet(indexOrAlias(), "type1", "1").setRouting("0").execute().actionGet().isExists(), equalTo(true));
} }
} }
@Test
public void testRequiredRoutingMapping_variousAPIs() throws Exception { public void testRequiredRoutingMapping_variousAPIs() throws Exception {
client().admin().indices().prepareCreate("test").addAlias(new Alias("alias")) client().admin().indices().prepareCreate("test").addAlias(new Alias("alias"))
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("_routing").field("required", true).endObject().endObject().endObject()) .addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("_routing").field("required", true).endObject().endObject().endObject())

View File

@ -75,7 +75,7 @@ public class SignificantTermsTests extends ElasticsearchIntegrationTest {
@Override @Override
public void setupSuiteScopeCluster() throws Exception { public void setupSuiteScopeCluster() throws Exception {
assertAcked(prepareCreate("test").setSettings(SETTING_NUMBER_OF_SHARDS, 5, SETTING_NUMBER_OF_REPLICAS, 0).addMapping("fact", assertAcked(prepareCreate("test").setSettings(SETTING_NUMBER_OF_SHARDS, 5, SETTING_NUMBER_OF_REPLICAS, 0).addMapping("fact",
"_routing", "required=true,path=routing_id", "routing_id", "type=string,index=not_analyzed", "fact_category", "_routing", "required=true", "routing_id", "type=string,index=not_analyzed", "fact_category",
"type=integer,index=not_analyzed", "description", "type=string,index=analyzed")); "type=integer,index=not_analyzed", "description", "type=string,index=analyzed"));
createIndex("idx_unmapped"); createIndex("idx_unmapped");
@ -105,7 +105,8 @@ public class SignificantTermsTests extends ElasticsearchIntegrationTest {
for (int i = 0; i < data.length; i++) { for (int i = 0; i < data.length; i++) {
String[] parts = data[i].split("\t"); String[] parts = data[i].split("\t");
client().prepareIndex("test", "fact", "" + i) client().prepareIndex("test", "fact", "" + i)
.setSource("routing_id", parts[0], "fact_category", parts[1], "description", parts[2]).get(); .setRouting(parts[0])
.setSource("fact_category", parts[1], "description", parts[2]).get();
} }
client().admin().indices().refresh(new RefreshRequest("test")).get(); client().admin().indices().refresh(new RefreshRequest("test")).get();
} }

View File

@ -52,7 +52,6 @@ public class TermsDocCountErrorTests extends ElasticsearchIntegrationTest{
private static final String STRING_FIELD_NAME = "s_value"; private static final String STRING_FIELD_NAME = "s_value";
private static final String LONG_FIELD_NAME = "l_value"; private static final String LONG_FIELD_NAME = "l_value";
private static final String DOUBLE_FIELD_NAME = "d_value"; private static final String DOUBLE_FIELD_NAME = "d_value";
private static final String ROUTING_FIELD_NAME = "route";
public static String randomExecutionHint() { public static String randomExecutionHint() {
return randomBoolean() ? null : randomFrom(ExecutionMode.values()).toString(); return randomBoolean() ? null : randomFrom(ExecutionMode.values()).toString();
@ -84,14 +83,15 @@ public class TermsDocCountErrorTests extends ElasticsearchIntegrationTest{
.endObject())); .endObject()));
} }
numRoutingValues = between(1,40); numRoutingValues = between(1,40);
assertAcked(prepareCreate("idx_with_routing").addMapping("type", "{ \"type\" : { \"_routing\" : { \"required\" : true, \"path\" : \"" + ROUTING_FIELD_NAME + "\" } } }")); assertAcked(prepareCreate("idx_with_routing").addMapping("type", "{ \"type\" : { \"_routing\" : { \"required\" : true } } }"));
for (int i = 0; i < numDocs; i++) { for (int i = 0; i < numDocs; i++) {
builders.add(client().prepareIndex("idx_single_shard", "type", ""+i).setSource(jsonBuilder() builders.add(client().prepareIndex("idx_single_shard", "type", "" + i)
.setRouting(String.valueOf(randomInt(numRoutingValues)))
.setSource(jsonBuilder()
.startObject() .startObject()
.field(STRING_FIELD_NAME, "val" + randomInt(numUniqueTerms)) .field(STRING_FIELD_NAME, "val" + randomInt(numUniqueTerms))
.field(LONG_FIELD_NAME, randomInt(numUniqueTerms)) .field(LONG_FIELD_NAME, randomInt(numUniqueTerms))
.field(DOUBLE_FIELD_NAME, 1.0 * randomInt(numUniqueTerms)) .field(DOUBLE_FIELD_NAME, 1.0 * randomInt(numUniqueTerms))
.field(ROUTING_FIELD_NAME, String.valueOf(randomInt(numRoutingValues)))
.endObject())); .endObject()));
} }
indexRandom(true, builders); indexRandom(true, builders);

View File

@ -1580,7 +1580,6 @@ public class SearchQueryTests extends ElasticsearchIntegrationTest {
.startObject("s") .startObject("s")
.startObject("_routing") .startObject("_routing")
.field("required", true) .field("required", true)
.field("path", "bs")
.endObject() .endObject()
.startObject("properties") .startObject("properties")
.startObject("online") .startObject("online")
@ -1601,8 +1600,8 @@ public class SearchQueryTests extends ElasticsearchIntegrationTest {
.addMapping("bs", "online", "type=boolean", "ts", "type=date,ignore_malformed=false,format=dateOptionalTime")); .addMapping("bs", "online", "type=boolean", "ts", "type=date,ignore_malformed=false,format=dateOptionalTime"));
ensureGreen(); ensureGreen();
client().prepareIndex("test", "s", "1").setSource("online", false, "bs", "Y", "ts", System.currentTimeMillis() - 100).get(); client().prepareIndex("test", "s", "1").setRouting("Y").setSource("online", false, "bs", "Y", "ts", System.currentTimeMillis() - 100).get();
client().prepareIndex("test", "s", "2").setSource("online", true, "bs", "X", "ts", System.currentTimeMillis() - 10000000).get(); client().prepareIndex("test", "s", "2").setRouting("X").setSource("online", true, "bs", "X", "ts", System.currentTimeMillis() - 10000000).get();
client().prepareIndex("test", "bs", "3").setSource("online", false, "ts", System.currentTimeMillis() - 100).get(); client().prepareIndex("test", "bs", "3").setSource("online", false, "ts", System.currentTimeMillis() - 100).get();
client().prepareIndex("test", "bs", "4").setSource("online", true, "ts", System.currentTimeMillis() - 123123).get(); client().prepareIndex("test", "bs", "4").setSource("online", true, "ts", System.currentTimeMillis() - 123123).get();
refresh(); refresh();