From e39b6a5689dc904f0fa9fa45ca97013d814b6bfe Mon Sep 17 00:00:00 2001 From: Martijn van Groningen Date: Thu, 9 Jul 2015 11:40:08 +0200 Subject: [PATCH 1/2] aliases: Don't require fields used in alias filters to exist --- .../cluster/metadata/AliasValidator.java | 1 - .../aliases/IndexAliasesTests.java | 34 +++++++------------ .../template/SimpleIndexTemplateTests.java | 29 ++++++++-------- 3 files changed, 26 insertions(+), 38 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java b/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java index c5d603ccca6..f12824de4ee 100644 --- a/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java +++ b/core/src/main/java/org/elasticsearch/cluster/metadata/AliasValidator.java @@ -145,7 +145,6 @@ public class AliasValidator extends AbstractComponent { QueryParseContext context = indexQueryParserService.getParseContext(); try { context.reset(parser); - context.setAllowUnmappedFields(false); context.parseInnerFilter(); } finally { context.reset(null); diff --git a/core/src/test/java/org/elasticsearch/aliases/IndexAliasesTests.java b/core/src/test/java/org/elasticsearch/aliases/IndexAliasesTests.java index 7b04674a008..dd8d66469b0 100644 --- a/core/src/test/java/org/elasticsearch/aliases/IndexAliasesTests.java +++ b/core/src/test/java/org/elasticsearch/aliases/IndexAliasesTests.java @@ -29,7 +29,6 @@ import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse; import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.SearchResponse; -import org.elasticsearch.action.search.SearchType; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.AliasAction; import org.elasticsearch.cluster.metadata.AliasMetaData; @@ -39,7 +38,6 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; -import org.elasticsearch.index.query.QueryParsingException; import org.elasticsearch.rest.action.admin.indices.alias.delete.AliasesMissingException; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; @@ -909,29 +907,21 @@ public class IndexAliasesTests extends ElasticsearchIntegrationTest { } @Test + // Before 2.0 alias filters were parsed at alias creation time, in order + // for filters to work correctly ES required that fields mentioned in those + // filters exist in the mapping. + // From 2.0 and higher alias filters are parsed at request time and therefor + // fields mentioned in filters don't need to exist in the mapping. public void testAddAliasWithFilterNoMapping() throws Exception { assertAcked(prepareCreate("test")); - - try { - client().admin().indices().prepareAliases() - .addAlias("test", "a", QueryBuilders.termQuery("field1", "term")) - .get(); - fail(); - } catch (IllegalArgumentException e) { - assertThat(e.getCause(), instanceOf(QueryParsingException.class)); - } - - try { - client().admin().indices().prepareAliases() - .addAlias("test", "a", QueryBuilders.rangeQuery("field2").from(0).to(1)) - .get(); - fail(); - } catch (IllegalArgumentException e) { - assertThat(e.getCause(), instanceOf(QueryParsingException.class)); - } - client().admin().indices().prepareAliases() - .addAlias("test", "a", QueryBuilders.matchAllQuery()) // <-- no fail, b/c no field mentioned + .addAlias("test", "a", QueryBuilders.termQuery("field1", "term")) + .get(); + client().admin().indices().prepareAliases() + .addAlias("test", "a", QueryBuilders.rangeQuery("field2").from(0).to(1)) + .get(); + client().admin().indices().prepareAliases() + .addAlias("test", "a", QueryBuilders.matchAllQuery()) .get(); } diff --git a/core/src/test/java/org/elasticsearch/indices/template/SimpleIndexTemplateTests.java b/core/src/test/java/org/elasticsearch/indices/template/SimpleIndexTemplateTests.java index 131e8ad73df..366a4cb96fd 100644 --- a/core/src/test/java/org/elasticsearch/indices/template/SimpleIndexTemplateTests.java +++ b/core/src/test/java/org/elasticsearch/indices/template/SimpleIndexTemplateTests.java @@ -20,9 +20,7 @@ package org.elasticsearch.indices.template; import com.google.common.collect.Lists; import com.google.common.collect.Sets; - import org.elasticsearch.ElasticsearchParseException; -import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.action.ActionRequestValidationException; import org.elasticsearch.action.admin.indices.alias.Alias; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse; @@ -33,7 +31,6 @@ import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.cluster.metadata.AliasMetaData; -import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.index.query.QueryBuilders; @@ -44,12 +41,10 @@ import org.elasticsearch.search.SearchHit; import org.elasticsearch.test.ElasticsearchIntegrationTest; import org.junit.Test; -import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.Set; -import static org.elasticsearch.index.query.QueryBuilders.termQuery; import static org.elasticsearch.index.query.QueryBuilders.termQuery; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*; import static org.hamcrest.Matchers.*; @@ -659,17 +654,21 @@ public class SimpleIndexTemplateTests extends ElasticsearchIntegrationTest { assertThat(response.getItems()[0].getId(), equalTo("test")); assertThat(response.getItems()[0].getVersion(), equalTo(1l)); - try { - client().prepareIndex("d1", "test", "test").setSource("{}").get(); - fail(); - } catch (Exception e) { - assertThat(ExceptionsHelper.unwrapCause(e), instanceOf(IllegalArgumentException.class)); - assertThat(e.getMessage(), containsString("failed to parse filter for alias [alias4]")); - } + // Before 2.0 alias filters were parsed at alias creation time, in order + // for filters to work correctly ES required that fields mentioned in those + // filters exist in the mapping. + // From 2.0 and higher alias filters are parsed at request time and therefor + // fields mentioned in filters don't need to exist in the mapping. + // So the aliases defined in the index template for this index will not fail + // even though the fields in the alias fields don't exist yet and indexing into + // an index that doesn't exist yet will succeed + client().prepareIndex("d1", "test", "test").setSource("{}").get(); + response = client().prepareBulk().add(new IndexRequest("d2", "test", "test").source("{}")).get(); - assertThat(response.hasFailures(), is(true)); - assertThat(response.getItems()[0].isFailed(), equalTo(true)); - assertThat(response.getItems()[0].getFailureMessage(), containsString("failed to parse filter for alias [alias4]")); + assertThat(response.hasFailures(), is(false)); + assertThat(response.getItems()[0].isFailed(), equalTo(false)); + assertThat(response.getItems()[0].getId(), equalTo("test")); + assertThat(response.getItems()[0].getVersion(), equalTo(1l)); } } From aa22e233161dff4f6b1b45165c20b4081bb22f87 Mon Sep 17 00:00:00 2001 From: Martijn van Groningen Date: Thu, 9 Jul 2015 12:07:49 +0200 Subject: [PATCH 2/2] added breaking docs --- docs/reference/migration/migrate_2_0.asciidoc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/reference/migration/migrate_2_0.asciidoc b/docs/reference/migration/migrate_2_0.asciidoc index 1aae0f4d89e..a1247b1023d 100644 --- a/docs/reference/migration/migrate_2_0.asciidoc +++ b/docs/reference/migration/migrate_2_0.asciidoc @@ -770,3 +770,8 @@ For the record, official plugins which can use this new simplified form are: * elasticsearch-lang-javascript * elasticsearch-lang-python +=== Aliases + +Fields used in alias filters no longer have to exist in the mapping upon alias creation time. Alias filters are now +parsed at request time and then the fields in filters are resolved from the mapping, whereas before alias filters were +parsed at alias creation time and the parsed form was kept around in memory. \ No newline at end of file