Mappings: Remove support for field access by short name

When multiple fields under object fields share the same name, accessing
by short name is ambiguous.  This removes support for short names,
always requiring the full name when used in queries.

closes #8872
This commit is contained in:
Ryan Ernst 2015-02-11 22:55:34 -08:00
parent 93fe4495ae
commit 533fdbdf75
14 changed files with 120 additions and 113 deletions

View File

@ -186,3 +186,49 @@ curl -XGET 'localhost:9200/index/t1,t2/_search'
} }
--------------- ---------------
==== Removed short name field access
Field names in queries, aggregations, etc. must now use the complete name. Use of the short name
caused ambiguities in field lookups when the same name existed within multiple object mappings.
The following example illustrates the difference between 1.x and 2.0.
Given these mappings:
---------------
curl -XPUT 'localhost:9200/index'
{
"mappings": {
"type": {
"properties": {
"name": {
"type": "object",
"properties": {
"first": {"type": "string"},
"last": {"type": "string"}
}
}
}
}
}
}
---------------
The following query was possible in 1.x:
---------------
curl -XGET 'localhost:9200/index/type/_search'
{
"query": {
"match": { "first": "foo" }
}
}
---------------
In 2.0, the same query should now be:
---------------
curl -XGET 'localhost:9200/index/type/_search'
{
"query": {
"match": { "name.first": "foo" }
}
}
---------------

View File

@ -79,8 +79,9 @@ public final class DocumentFieldMappers extends ForwardingSet<FieldMapper<?>> {
return new DocumentFieldMappers(fieldMappers, indexAnalyzer, searchAnalyzer, searchQuoteAnalyzer); return new DocumentFieldMappers(fieldMappers, indexAnalyzer, searchAnalyzer, searchQuoteAnalyzer);
} }
// TODO: replace all uses of this with fullName, or change the meaning of name to be fullName
public FieldMappers name(String name) { public FieldMappers name(String name) {
return fieldMappers.name(name); return fieldMappers.fullName(name);
} }
public FieldMappers indexName(String indexName) { public FieldMappers indexName(String indexName) {

View File

@ -103,7 +103,10 @@ public class FieldMappersLookup extends ForwardingSet<FieldMapper<?>> {
/** Create a new empty instance. */ /** Create a new empty instance. */
public FieldMappersLookup() { public FieldMappersLookup() {
this(new CopyOnWriteHashSet<FieldMapper<?>>(), new MappersLookup(new CopyOnWriteHashMap<String, FieldMappers>(), new CopyOnWriteHashMap<String, FieldMappers>(), new CopyOnWriteHashMap<String, FieldMappers>())); this(new CopyOnWriteHashSet<FieldMapper<?>>(),
new MappersLookup(new CopyOnWriteHashMap<String, FieldMappers>(),
new CopyOnWriteHashMap<String, FieldMappers>(),
new CopyOnWriteHashMap<String, FieldMappers>()));
} }
private FieldMappersLookup(CopyOnWriteHashSet<FieldMapper<?>> mappers, MappersLookup lookup) { private FieldMappersLookup(CopyOnWriteHashSet<FieldMapper<?>> mappers, MappersLookup lookup) {
@ -130,13 +133,6 @@ public class FieldMappersLookup extends ForwardingSet<FieldMapper<?>> {
} }
} }
/**
* Returns the field mappers based on the mapper name.
*/
public FieldMappers name(String name) {
return lookup.name.get(name);
}
/** /**
* Returns the field mappers based on the mapper index name. * Returns the field mappers based on the mapper index name.
*/ */
@ -152,7 +148,7 @@ public class FieldMappersLookup extends ForwardingSet<FieldMapper<?>> {
} }
/** /**
* Returns a list of the index names of a simple match regex like pattern against full name, name and index name. * Returns a list of the index names of a simple match regex like pattern against full name and index name.
*/ */
public List<String> simpleMatchToIndexNames(String pattern) { public List<String> simpleMatchToIndexNames(String pattern) {
List<String> fields = Lists.newArrayList(); List<String> fields = Lists.newArrayList();
@ -161,15 +157,13 @@ public class FieldMappersLookup extends ForwardingSet<FieldMapper<?>> {
fields.add(fieldMapper.names().indexName()); fields.add(fieldMapper.names().indexName());
} else if (Regex.simpleMatch(pattern, fieldMapper.names().indexName())) { } else if (Regex.simpleMatch(pattern, fieldMapper.names().indexName())) {
fields.add(fieldMapper.names().indexName()); fields.add(fieldMapper.names().indexName());
} else if (Regex.simpleMatch(pattern, fieldMapper.names().name())) {
fields.add(fieldMapper.names().indexName());
} }
} }
return fields; return fields;
} }
/** /**
* Returns a list of the full names of a simple match regex like pattern against full name, name and index name. * Returns a list of the full names of a simple match regex like pattern against full name and index name.
*/ */
public List<String> simpleMatchToFullName(String pattern) { public List<String> simpleMatchToFullName(String pattern) {
List<String> fields = Lists.newArrayList(); List<String> fields = Lists.newArrayList();
@ -178,16 +172,13 @@ public class FieldMappersLookup extends ForwardingSet<FieldMapper<?>> {
fields.add(fieldMapper.names().fullName()); fields.add(fieldMapper.names().fullName());
} else if (Regex.simpleMatch(pattern, fieldMapper.names().indexName())) { } else if (Regex.simpleMatch(pattern, fieldMapper.names().indexName())) {
fields.add(fieldMapper.names().fullName()); fields.add(fieldMapper.names().fullName());
} else if (Regex.simpleMatch(pattern, fieldMapper.names().name())) {
fields.add(fieldMapper.names().fullName());
} }
} }
return fields; return fields;
} }
/** /**
* Tries to find first based on {@link #fullName(String)}, then by {@link #indexName(String)}, and last * Tries to find first based on {@link #fullName(String)}, then by {@link #indexName(String)}.
* by {@link #name(String)}.
*/ */
@Nullable @Nullable
public FieldMappers smartName(String name) { public FieldMappers smartName(String name) {
@ -195,16 +186,12 @@ public class FieldMappersLookup extends ForwardingSet<FieldMapper<?>> {
if (fieldMappers != null) { if (fieldMappers != null) {
return fieldMappers; return fieldMappers;
} }
fieldMappers = indexName(name); return indexName(name);
if (fieldMappers != null) {
return fieldMappers;
}
return name(name);
} }
/** /**
* Tries to find first based on {@link #fullName(String)}, then by {@link #indexName(String)}, and last * Tries to find first based on {@link #fullName(String)}, then by {@link #indexName(String)}
* by {@link #name(String)} and return the first mapper for it (see {@link org.elasticsearch.index.mapper.FieldMappers#mapper()}). * and return the first mapper for it (see {@link org.elasticsearch.index.mapper.FieldMappers#mapper()}).
*/ */
@Nullable @Nullable
public FieldMapper<?> smartNameFieldMapper(String name) { public FieldMapper<?> smartNameFieldMapper(String name) {

View File

@ -558,17 +558,6 @@ public class MapperService extends AbstractIndexComponent {
} }
} }
/**
* Returns {@link FieldMappers} for all the {@link FieldMapper}s that are registered
* under the given name across all the different {@link DocumentMapper} types.
*
* @param name The name to return all the {@link FieldMappers} for across all {@link DocumentMapper}s.
* @return All the {@link FieldMappers} for across all {@link DocumentMapper}s
*/
public FieldMappers name(String name) {
return fieldMappers.name(name);
}
/** /**
* Returns {@link FieldMappers} for all the {@link FieldMapper}s that are registered * Returns {@link FieldMappers} for all the {@link FieldMapper}s that are registered
* under the given indexName across all the different {@link DocumentMapper} types. * under the given indexName across all the different {@link DocumentMapper} types.
@ -706,11 +695,7 @@ public class MapperService extends AbstractIndexComponent {
if (mappers != null) { if (mappers != null) {
return mappers; return mappers;
} }
mappers = indexName(smartName); return indexName(smartName);
if (mappers != null) {
return mappers;
}
return name(smartName);
} }
public SmartNameFieldMappers smartName(String smartName, @Nullable String[] types) { public SmartNameFieldMappers smartName(String smartName, @Nullable String[] types) {
@ -755,10 +740,6 @@ public class MapperService extends AbstractIndexComponent {
if (fieldMappers != null) { if (fieldMappers != null) {
return new SmartNameFieldMappers(this, fieldMappers, null, false); return new SmartNameFieldMappers(this, fieldMappers, null, false);
} }
fieldMappers = name(smartName);
if (fieldMappers != null) {
return new SmartNameFieldMappers(this, fieldMappers, null, false);
}
return null; return null;
} }

View File

@ -170,7 +170,7 @@ public class IndicesTTLService extends AbstractLifecycleComponent<IndicesTTLServ
} }
// should be optimized with the hasTTL flag // should be optimized with the hasTTL flag
FieldMappers ttlFieldMappers = indexService.mapperService().name(TTLFieldMapper.NAME); FieldMappers ttlFieldMappers = indexService.mapperService().fullName(TTLFieldMapper.NAME);
if (ttlFieldMappers == null) { if (ttlFieldMappers == null) {
continue; continue;
} }

View File

@ -102,7 +102,7 @@ public class DocumentActionsTests extends ElasticsearchIntegrationTest {
getResult = client().prepareGet("test", "type1", "1").setOperationThreaded(false).execute().actionGet(); getResult = client().prepareGet("test", "type1", "1").setOperationThreaded(false).execute().actionGet();
assertThat(getResult.getIndex(), equalTo(getConcreteIndexName())); assertThat(getResult.getIndex(), equalTo(getConcreteIndexName()));
assertThat("cycle #" + i, getResult.getSourceAsString(), equalTo(source("1", "test").string())); assertThat("cycle #" + i, getResult.getSourceAsString(), equalTo(source("1", "test").string()));
assertThat("cycle(map) #" + i, (String) ((Map) getResult.getSourceAsMap().get("type1")).get("name"), equalTo("test")); assertThat("cycle(map) #" + i, (String) getResult.getSourceAsMap().get("name"), equalTo("test"));
getResult = client().get(getRequest("test").type("type1").id("1").operationThreaded(true)).actionGet(); getResult = client().get(getRequest("test").type("type1").id("1").operationThreaded(true)).actionGet();
assertThat("cycle #" + i, getResult.getSourceAsString(), equalTo(source("1", "test").string())); assertThat("cycle #" + i, getResult.getSourceAsString(), equalTo(source("1", "test").string()));
assertThat(getResult.getIndex(), equalTo(getConcreteIndexName())); assertThat(getResult.getIndex(), equalTo(getConcreteIndexName()));
@ -110,11 +110,11 @@ public class DocumentActionsTests extends ElasticsearchIntegrationTest {
logger.info("Get [type1/1] with script"); logger.info("Get [type1/1] with script");
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
getResult = client().prepareGet("test", "type1", "1").setFields("type1.name").execute().actionGet(); getResult = client().prepareGet("test", "type1", "1").setFields("name").execute().actionGet();
assertThat(getResult.getIndex(), equalTo(getConcreteIndexName())); assertThat(getResult.getIndex(), equalTo(getConcreteIndexName()));
assertThat(getResult.isExists(), equalTo(true)); assertThat(getResult.isExists(), equalTo(true));
assertThat(getResult.getSourceAsBytes(), nullValue()); assertThat(getResult.getSourceAsBytes(), nullValue());
assertThat(getResult.getField("type1.name").getValues().get(0).toString(), equalTo("test")); assertThat(getResult.getField("name").getValues().get(0).toString(), equalTo("test"));
} }
logger.info("Get [type1/2] (should be empty)"); logger.info("Get [type1/2] (should be empty)");
@ -321,6 +321,6 @@ public class DocumentActionsTests extends ElasticsearchIntegrationTest {
} }
private XContentBuilder source(String id, String nameValue) throws IOException { private XContentBuilder source(String id, String nameValue) throws IOException {
return XContentFactory.jsonBuilder().startObject().startObject("type1").field("id", id).field("name", nameValue).endObject().endObject(); return XContentFactory.jsonBuilder().startObject().field("id", id).field("name", nameValue).endObject();
} }
} }

View File

@ -53,8 +53,7 @@ public class SimpleMapperTests extends ElasticsearchSingleNodeTest {
BytesReference json = new BytesArray(copyToBytesFromClasspath("/org/elasticsearch/index/mapper/simple/test1.json")); BytesReference json = new BytesArray(copyToBytesFromClasspath("/org/elasticsearch/index/mapper/simple/test1.json"));
Document doc = docMapper.parse("person", "1", json).rootDoc(); Document doc = docMapper.parse("person", "1", json).rootDoc();
assertThat(doc.get(docMapper.mappers().name("first").mapper().names().indexName()), equalTo("shay")); assertThat(doc.get(docMapper.mappers().name("name.first").mapper().names().indexName()), equalTo("shay"));
assertThat(docMapper.mappers().name("first").mapper().names().fullName(), equalTo("name.first"));
// System.out.println("Document: " + doc); // System.out.println("Document: " + doc);
// System.out.println("Json: " + docMapper.sourceMapper().value(doc)); // System.out.println("Json: " + docMapper.sourceMapper().value(doc));
doc = docMapper.parse(json).rootDoc(); doc = docMapper.parse(json).rootDoc();
@ -74,7 +73,7 @@ public class SimpleMapperTests extends ElasticsearchSingleNodeTest {
BytesReference json = new BytesArray(copyToBytesFromClasspath("/org/elasticsearch/index/mapper/simple/test1.json")); BytesReference json = new BytesArray(copyToBytesFromClasspath("/org/elasticsearch/index/mapper/simple/test1.json"));
Document doc = builtDocMapper.parse(json).rootDoc(); Document doc = builtDocMapper.parse(json).rootDoc();
assertThat(doc.get(docMapper.uidMapper().names().indexName()), equalTo(Uid.createUid("person", "1"))); assertThat(doc.get(docMapper.uidMapper().names().indexName()), equalTo(Uid.createUid("person", "1")));
assertThat(doc.get(docMapper.mappers().name("first").mapper().names().indexName()), equalTo("shay")); assertThat(doc.get(docMapper.mappers().name("name.first").mapper().names().indexName()), equalTo("shay"));
// System.out.println("Document: " + doc); // System.out.println("Document: " + doc);
// System.out.println("Json: " + docMapper.sourceMapper().value(doc)); // System.out.println("Json: " + docMapper.sourceMapper().value(doc));
} }
@ -89,7 +88,7 @@ public class SimpleMapperTests extends ElasticsearchSingleNodeTest {
BytesReference json = new BytesArray(copyToBytesFromClasspath("/org/elasticsearch/index/mapper/simple/test1.json")); BytesReference json = new BytesArray(copyToBytesFromClasspath("/org/elasticsearch/index/mapper/simple/test1.json"));
Document doc = docMapper.parse(json).rootDoc(); Document doc = docMapper.parse(json).rootDoc();
assertThat(doc.get(docMapper.uidMapper().names().indexName()), equalTo(Uid.createUid("person", "1"))); assertThat(doc.get(docMapper.uidMapper().names().indexName()), equalTo(Uid.createUid("person", "1")));
assertThat(doc.get(docMapper.mappers().name("first").mapper().names().indexName()), equalTo("shay")); assertThat(doc.get(docMapper.mappers().name("name.first").mapper().names().indexName()), equalTo("shay"));
// System.out.println("Document: " + doc); // System.out.println("Document: " + doc);
// System.out.println("Json: " + docMapper.sourceMapper().value(doc)); // System.out.println("Json: " + docMapper.sourceMapper().value(doc));
} }
@ -101,7 +100,7 @@ public class SimpleMapperTests extends ElasticsearchSingleNodeTest {
BytesReference json = new BytesArray(copyToBytesFromClasspath("/org/elasticsearch/index/mapper/simple/test1-notype-noid.json")); BytesReference json = new BytesArray(copyToBytesFromClasspath("/org/elasticsearch/index/mapper/simple/test1-notype-noid.json"));
Document doc = docMapper.parse("person", "1", json).rootDoc(); Document doc = docMapper.parse("person", "1", json).rootDoc();
assertThat(doc.get(docMapper.uidMapper().names().indexName()), equalTo(Uid.createUid("person", "1"))); assertThat(doc.get(docMapper.uidMapper().names().indexName()), equalTo(Uid.createUid("person", "1")));
assertThat(doc.get(docMapper.mappers().name("first").mapper().names().indexName()), equalTo("shay")); assertThat(doc.get(docMapper.mappers().name("name.first").mapper().names().indexName()), equalTo("shay"));
// System.out.println("Document: " + doc); // System.out.println("Document: " + doc);
// System.out.println("Json: " + docMapper.sourceMapper().value(doc)); // System.out.println("Json: " + docMapper.sourceMapper().value(doc));
} }

View File

@ -33,12 +33,8 @@ import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
/**
*
*/
public class SimpleGetFieldMappingsTests extends ElasticsearchIntegrationTest { public class SimpleGetFieldMappingsTests extends ElasticsearchIntegrationTest {
@Test
public void getMappingsWhereThereAreNone() { public void getMappingsWhereThereAreNone() {
createIndex("index"); createIndex("index");
ensureYellow(); ensureYellow();
@ -56,7 +52,6 @@ public class SimpleGetFieldMappingsTests extends ElasticsearchIntegrationTest {
.endObject().endObject().endObject(); .endObject().endObject().endObject();
} }
@Test
public void simpleGetFieldMappings() throws Exception { public void simpleGetFieldMappings() throws Exception {
assertAcked(prepareCreate("indexa") assertAcked(prepareCreate("indexa")
@ -80,55 +75,54 @@ public class SimpleGetFieldMappingsTests extends ElasticsearchIntegrationTest {
assertThat(response.fieldMappings("indexb", "typeB", "field1"), nullValue()); assertThat(response.fieldMappings("indexb", "typeB", "field1"), nullValue());
// Get mappings by name // Get mappings by name
response = client().admin().indices().prepareGetFieldMappings("indexa").setTypes("typeA").setFields("field1", "subfield").get(); response = client().admin().indices().prepareGetFieldMappings("indexa").setTypes("typeA").setFields("field1", "obj.subfield").get();
assertThat(response.fieldMappings("indexa", "typeA", "field1").fullName(), equalTo("field1")); assertThat(response.fieldMappings("indexa", "typeA", "field1").fullName(), equalTo("field1"));
assertThat(response.fieldMappings("indexa", "typeA", "field1").sourceAsMap(), hasKey("field1")); assertThat(response.fieldMappings("indexa", "typeA", "field1").sourceAsMap(), hasKey("field1"));
assertThat(response.fieldMappings("indexa", "typeA", "subfield").fullName(), equalTo("obj.subfield")); assertThat(response.fieldMappings("indexa", "typeA", "obj.subfield").fullName(), equalTo("obj.subfield"));
assertThat(response.fieldMappings("indexa", "typeA", "subfield").sourceAsMap(), hasKey("subfield")); assertThat(response.fieldMappings("indexa", "typeA", "obj.subfield").sourceAsMap(), hasKey("subfield"));
assertThat(response.fieldMappings("indexa", "typeB", "field1"), nullValue()); assertThat(response.fieldMappings("indexa", "typeB", "field1"), nullValue());
assertThat(response.fieldMappings("indexb", "typeB", "field1"), nullValue()); assertThat(response.fieldMappings("indexb", "typeB", "field1"), nullValue());
// get mappings by name across multiple indices // get mappings by name across multiple indices
response = client().admin().indices().prepareGetFieldMappings().setTypes("typeA").setFields("subfield").get(); response = client().admin().indices().prepareGetFieldMappings().setTypes("typeA").setFields("obj.subfield").get();
assertThat(response.fieldMappings("indexa", "typeA", "subfield").fullName(), equalTo("obj.subfield")); assertThat(response.fieldMappings("indexa", "typeA", "obj.subfield").fullName(), equalTo("obj.subfield"));
assertThat(response.fieldMappings("indexa", "typeA", "subfield").sourceAsMap(), hasKey("subfield")); assertThat(response.fieldMappings("indexa", "typeA", "obj.subfield").sourceAsMap(), hasKey("subfield"));
assertThat(response.fieldMappings("indexa", "typeB", "subfield"), nullValue()); assertThat(response.fieldMappings("indexa", "typeB", "obj.subfield"), nullValue());
assertThat(response.fieldMappings("indexb", "typeA", "subfield").fullName(), equalTo("obj.subfield")); assertThat(response.fieldMappings("indexb", "typeA", "obj.subfield").fullName(), equalTo("obj.subfield"));
assertThat(response.fieldMappings("indexb", "typeA", "subfield").sourceAsMap(), hasKey("subfield")); assertThat(response.fieldMappings("indexb", "typeA", "obj.subfield").sourceAsMap(), hasKey("subfield"));
assertThat(response.fieldMappings("indexb", "typeB", "subfield"), nullValue()); assertThat(response.fieldMappings("indexb", "typeB", "obj.subfield"), nullValue());
// get mappings by name across multiple types // get mappings by name across multiple types
response = client().admin().indices().prepareGetFieldMappings("indexa").setFields("subfield").get(); response = client().admin().indices().prepareGetFieldMappings("indexa").setFields("obj.subfield").get();
assertThat(response.fieldMappings("indexa", "typeA", "subfield").fullName(), equalTo("obj.subfield")); assertThat(response.fieldMappings("indexa", "typeA", "obj.subfield").fullName(), equalTo("obj.subfield"));
assertThat(response.fieldMappings("indexa", "typeA", "subfield").sourceAsMap(), hasKey("subfield")); assertThat(response.fieldMappings("indexa", "typeA", "obj.subfield").sourceAsMap(), hasKey("subfield"));
assertThat(response.fieldMappings("indexa", "typeA", "field1"), nullValue()); assertThat(response.fieldMappings("indexa", "typeA", "field1"), nullValue());
assertThat(response.fieldMappings("indexa", "typeB", "subfield").fullName(), equalTo("obj.subfield")); assertThat(response.fieldMappings("indexa", "typeB", "obj.subfield").fullName(), equalTo("obj.subfield"));
assertThat(response.fieldMappings("indexa", "typeB", "subfield").sourceAsMap(), hasKey("subfield")); assertThat(response.fieldMappings("indexa", "typeB", "obj.subfield").sourceAsMap(), hasKey("subfield"));
assertThat(response.fieldMappings("indexa", "typeB", "field1"), nullValue()); assertThat(response.fieldMappings("indexa", "typeB", "field1"), nullValue());
assertThat(response.fieldMappings("indexb", "typeA", "subfield"), nullValue()); assertThat(response.fieldMappings("indexb", "typeA", "obj.subfield"), nullValue());
assertThat(response.fieldMappings("indexb", "typeA", "field1"), nullValue()); assertThat(response.fieldMappings("indexb", "typeA", "field1"), nullValue());
assertThat(response.fieldMappings("indexb", "typeB", "subfield"), nullValue()); assertThat(response.fieldMappings("indexb", "typeB", "obj.subfield"), nullValue());
assertThat(response.fieldMappings("indexb", "typeB", "field1"), nullValue()); assertThat(response.fieldMappings("indexb", "typeB", "field1"), nullValue());
// get mappings by name across multiple types & indices // get mappings by name across multiple types & indices
response = client().admin().indices().prepareGetFieldMappings().setFields("subfield").get(); response = client().admin().indices().prepareGetFieldMappings().setFields("obj.subfield").get();
assertThat(response.fieldMappings("indexa", "typeA", "subfield").fullName(), equalTo("obj.subfield")); assertThat(response.fieldMappings("indexa", "typeA", "obj.subfield").fullName(), equalTo("obj.subfield"));
assertThat(response.fieldMappings("indexa", "typeA", "subfield").sourceAsMap(), hasKey("subfield")); assertThat(response.fieldMappings("indexa", "typeA", "obj.subfield").sourceAsMap(), hasKey("subfield"));
assertThat(response.fieldMappings("indexa", "typeA", "field1"), nullValue()); assertThat(response.fieldMappings("indexa", "typeA", "field1"), nullValue());
assertThat(response.fieldMappings("indexa", "typeB", "subfield").fullName(), equalTo("obj.subfield")); assertThat(response.fieldMappings("indexa", "typeB", "obj.subfield").fullName(), equalTo("obj.subfield"));
assertThat(response.fieldMappings("indexa", "typeB", "subfield").sourceAsMap(), hasKey("subfield")); assertThat(response.fieldMappings("indexa", "typeB", "obj.subfield").sourceAsMap(), hasKey("subfield"));
assertThat(response.fieldMappings("indexa", "typeB", "field1"), nullValue()); assertThat(response.fieldMappings("indexa", "typeB", "field1"), nullValue());
assertThat(response.fieldMappings("indexb", "typeA", "subfield").fullName(), equalTo("obj.subfield")); assertThat(response.fieldMappings("indexb", "typeA", "obj.subfield").fullName(), equalTo("obj.subfield"));
assertThat(response.fieldMappings("indexb", "typeA", "subfield").sourceAsMap(), hasKey("subfield")); assertThat(response.fieldMappings("indexb", "typeA", "obj.subfield").sourceAsMap(), hasKey("subfield"));
assertThat(response.fieldMappings("indexb", "typeB", "field1"), nullValue()); assertThat(response.fieldMappings("indexb", "typeB", "field1"), nullValue());
assertThat(response.fieldMappings("indexb", "typeB", "subfield").fullName(), equalTo("obj.subfield")); assertThat(response.fieldMappings("indexb", "typeB", "obj.subfield").fullName(), equalTo("obj.subfield"));
assertThat(response.fieldMappings("indexb", "typeB", "subfield").sourceAsMap(), hasKey("subfield")); assertThat(response.fieldMappings("indexb", "typeB", "obj.subfield").sourceAsMap(), hasKey("subfield"));
assertThat(response.fieldMappings("indexb", "typeB", "field1"), nullValue()); assertThat(response.fieldMappings("indexb", "typeB", "field1"), nullValue());
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Test
public void simpleGetFieldMappingsWithDefaults() throws Exception { public void simpleGetFieldMappingsWithDefaults() throws Exception {
assertAcked(prepareCreate("test").addMapping("type", getMappingForType("type"))); assertAcked(prepareCreate("test").addMapping("type", getMappingForType("type")));
@ -136,20 +130,19 @@ public class SimpleGetFieldMappingsTests extends ElasticsearchIntegrationTest {
ensureYellow(); ensureYellow();
waitForConcreteMappingsOnAll("test", "type", "num"); // for num, we need to wait... waitForConcreteMappingsOnAll("test", "type", "num"); // for num, we need to wait...
GetFieldMappingsResponse response = client().admin().indices().prepareGetFieldMappings().setFields("num", "field1", "subfield").includeDefaults(true).get(); GetFieldMappingsResponse response = client().admin().indices().prepareGetFieldMappings().setFields("num", "field1", "obj.subfield").includeDefaults(true).get();
assertThat((Map<String, Object>) response.fieldMappings("test", "type", "num").sourceAsMap().get("num"), hasEntry("index", (Object) "not_analyzed")); assertThat((Map<String, Object>) response.fieldMappings("test", "type", "num").sourceAsMap().get("num"), hasEntry("index", (Object) "not_analyzed"));
assertThat((Map<String, Object>) response.fieldMappings("test", "type", "num").sourceAsMap().get("num"), hasEntry("type", (Object) "long")); assertThat((Map<String, Object>) response.fieldMappings("test", "type", "num").sourceAsMap().get("num"), hasEntry("type", (Object) "long"));
assertThat((Map<String, Object>) response.fieldMappings("test", "type", "field1").sourceAsMap().get("field1"), hasEntry("index", (Object) "analyzed")); assertThat((Map<String, Object>) response.fieldMappings("test", "type", "field1").sourceAsMap().get("field1"), hasEntry("index", (Object) "analyzed"));
assertThat((Map<String, Object>) response.fieldMappings("test", "type", "field1").sourceAsMap().get("field1"), hasEntry("type", (Object) "string")); assertThat((Map<String, Object>) response.fieldMappings("test", "type", "field1").sourceAsMap().get("field1"), hasEntry("type", (Object) "string"));
assertThat((Map<String, Object>) response.fieldMappings("test", "type", "subfield").sourceAsMap().get("subfield"), hasEntry("index", (Object) "not_analyzed")); assertThat((Map<String, Object>) response.fieldMappings("test", "type", "obj.subfield").sourceAsMap().get("subfield"), hasEntry("index", (Object) "not_analyzed"));
assertThat((Map<String, Object>) response.fieldMappings("test", "type", "subfield").sourceAsMap().get("subfield"), hasEntry("type", (Object) "string")); assertThat((Map<String, Object>) response.fieldMappings("test", "type", "obj.subfield").sourceAsMap().get("subfield"), hasEntry("type", (Object) "string"));
} }
//fix #6552 //fix #6552
@Test
public void simpleGetFieldMappingsWithPretty() throws Exception { public void simpleGetFieldMappingsWithPretty() throws Exception {
assertAcked(prepareCreate("index").addMapping("type", getMappingForType("type"))); assertAcked(prepareCreate("index").addMapping("type", getMappingForType("type")));
Map<String, String> params = Maps.newHashMap(); Map<String, String> params = Maps.newHashMap();

View File

@ -101,11 +101,11 @@ public class SimpleNestedTests extends ElasticsearchIntegrationTest {
assertThat(searchResponse.getHits().totalHits(), equalTo(0l)); assertThat(searchResponse.getHits().totalHits(), equalTo(0l));
// now, do a nested query // now, do a nested query
searchResponse = client().prepareSearch("test").setQuery(nestedQuery("nested1", termQuery("n_field1", "n_value1_1"))).get(); searchResponse = client().prepareSearch("test").setQuery(nestedQuery("nested1", termQuery("nested1.n_field1", "n_value1_1"))).get();
assertNoFailures(searchResponse); assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(1l)); assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
searchResponse = client().prepareSearch("test").setQuery(nestedQuery("nested1", termQuery("n_field1", "n_value1_1"))).setSearchType(SearchType.DFS_QUERY_THEN_FETCH).get(); searchResponse = client().prepareSearch("test").setQuery(nestedQuery("nested1", termQuery("nested1.n_field1", "n_value1_1"))).setSearchType(SearchType.DFS_QUERY_THEN_FETCH).get();
assertNoFailures(searchResponse); assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(1l)); assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
@ -130,19 +130,19 @@ public class SimpleNestedTests extends ElasticsearchIntegrationTest {
assertDocumentCount("test", 6); assertDocumentCount("test", 6);
searchResponse = client().prepareSearch("test").setQuery(nestedQuery("nested1", searchResponse = client().prepareSearch("test").setQuery(nestedQuery("nested1",
boolQuery().must(termQuery("n_field1", "n_value1_1")).must(termQuery("n_field2", "n_value2_1")))).execute().actionGet(); boolQuery().must(termQuery("nested1.n_field1", "n_value1_1")).must(termQuery("nested1.n_field2", "n_value2_1")))).execute().actionGet();
assertNoFailures(searchResponse); assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(1l)); assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
// filter // filter
searchResponse = client().prepareSearch("test").setQuery(filteredQuery(matchAllQuery(), nestedFilter("nested1", searchResponse = client().prepareSearch("test").setQuery(filteredQuery(matchAllQuery(), nestedFilter("nested1",
boolQuery().must(termQuery("n_field1", "n_value1_1")).must(termQuery("n_field2", "n_value2_1"))))).execute().actionGet(); boolQuery().must(termQuery("nested1.n_field1", "n_value1_1")).must(termQuery("nested1.n_field2", "n_value2_1"))))).execute().actionGet();
assertNoFailures(searchResponse); assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(1l)); assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
// check with type prefix // check with type prefix
searchResponse = client().prepareSearch("test").setQuery(nestedQuery("nested1", searchResponse = client().prepareSearch("test").setQuery(nestedQuery("nested1",
boolQuery().must(termQuery("n_field1", "n_value1_1")).must(termQuery("n_field2", "n_value2_1")))).execute().actionGet(); boolQuery().must(termQuery("nested1.n_field1", "n_value1_1")).must(termQuery("nested1.n_field2", "n_value2_1")))).execute().actionGet();
assertNoFailures(searchResponse); assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(1l)); assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
@ -154,11 +154,11 @@ public class SimpleNestedTests extends ElasticsearchIntegrationTest {
flush(); flush();
assertDocumentCount("test", 3); assertDocumentCount("test", 3);
searchResponse = client().prepareSearch("test").setQuery(nestedQuery("nested1", termQuery("n_field1", "n_value1_1"))).execute().actionGet(); searchResponse = client().prepareSearch("test").setQuery(nestedQuery("nested1", termQuery("nested1.n_field1", "n_value1_1"))).execute().actionGet();
assertNoFailures(searchResponse); assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(1l)); assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
searchResponse = client().prepareSearch("test").setTypes("type1", "type2").setQuery(nestedQuery("nested1", termQuery("n_field1", "n_value1_1"))).execute().actionGet(); searchResponse = client().prepareSearch("test").setTypes("type1", "type2").setQuery(nestedQuery("nested1", termQuery("nested1.n_field1", "n_value1_1"))).execute().actionGet();
assertNoFailures(searchResponse); assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(1l)); assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
} }

View File

@ -1748,10 +1748,10 @@ public class PercolatorTests extends ElasticsearchIntegrationTest {
// The previous percolate request introduced the custom.color field, so now we register the query again // The previous percolate request introduced the custom.color field, so now we register the query again
// and the field name `color` will be resolved to `custom.color` field in mapping via smart field mapping resolving. // and the field name `color` will be resolved to `custom.color` field in mapping via smart field mapping resolving.
client().prepareIndex("idx", PercolatorService.TYPE_NAME, "1") client().prepareIndex("idx", PercolatorService.TYPE_NAME, "1")
.setSource(jsonBuilder().startObject().field("query", QueryBuilders.queryStringQuery("color:red")).endObject()) .setSource(jsonBuilder().startObject().field("query", QueryBuilders.queryStringQuery("custom.color:red")).endObject())
.get(); .get();
client().prepareIndex("idx", PercolatorService.TYPE_NAME, "2") client().prepareIndex("idx", PercolatorService.TYPE_NAME, "2")
.setSource(jsonBuilder().startObject().field("query", QueryBuilders.queryStringQuery("color:blue")).field("type", "type").endObject()) .setSource(jsonBuilder().startObject().field("query", QueryBuilders.queryStringQuery("custom.color:blue")).field("type", "type").endObject())
.get(); .get();
// The second request will yield a match, since the query during the proper field during parsing. // The second request will yield a match, since the query during the proper field during parsing.

View File

@ -565,7 +565,7 @@ public class ReverseNestedTests extends ElasticsearchIntegrationTest {
reverseNested("to_root").subAggregation( reverseNested("to_root").subAggregation(
nested("nested_1").path("sku").subAggregation( nested("nested_1").path("sku").subAggregation(
filter("filter_by_sku").filter(termFilter("sku.sku_type", "bar1")).subAggregation( filter("filter_by_sku").filter(termFilter("sku.sku_type", "bar1")).subAggregation(
count("sku_count").field("sku_type") count("sku_count").field("sku.sku_type")
) )
) )
) )
@ -603,7 +603,7 @@ public class ReverseNestedTests extends ElasticsearchIntegrationTest {
nested("nested_2").path("sku.colors").subAggregation( nested("nested_2").path("sku.colors").subAggregation(
filter("filter_sku_color").filter(termFilter("sku.colors.name", "red")).subAggregation( filter("filter_sku_color").filter(termFilter("sku.colors.name", "red")).subAggregation(
reverseNested("reverse_to_sku").path("sku").subAggregation( reverseNested("reverse_to_sku").path("sku").subAggregation(
count("sku_count").field("sku_type") count("sku_count").field("sku.sku_type")
) )
) )
) )

View File

@ -46,6 +46,7 @@ import org.junit.Test;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.common.xcontent.XContentFactory.smileBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.smileBuilder;
@ -778,13 +779,13 @@ public class TopHitsTests extends ElasticsearchIntegrationTest {
@Test @Test
public void testNestedFetchFeatures() { public void testNestedFetchFeatures() {
String hlType = randomFrom("plain", "fvh", "postings"); String hlType = randomFrom("plain", "fvh", "postings");
HighlightBuilder.Field hlField = new HighlightBuilder.Field("message") HighlightBuilder.Field hlField = new HighlightBuilder.Field("comments.message")
.highlightQuery(matchQuery("comments.message", "comment")) .highlightQuery(matchQuery("comments.message", "comment"))
.forceSource(randomBoolean()) // randomly from stored field or _source .forceSource(randomBoolean()) // randomly from stored field or _source
.highlighterType(hlType); .highlighterType(hlType);
SearchResponse searchResponse = client().prepareSearch("articles") SearchResponse searchResponse = client().prepareSearch("articles")
.setQuery(nestedQuery("comments", matchQuery("message", "comment").queryName("test"))) .setQuery(nestedQuery("comments", matchQuery("comments.message", "comment").queryName("test")))
.addAggregation( .addAggregation(
nested("to-comments") nested("to-comments")
.path("comments") .path("comments")
@ -811,7 +812,7 @@ public class TopHitsTests extends ElasticsearchIntegrationTest {
assertThat(searchHit.getNestedIdentity().getField().string(), equalTo("comments")); assertThat(searchHit.getNestedIdentity().getField().string(), equalTo("comments"));
assertThat(searchHit.getNestedIdentity().getOffset(), equalTo(0)); assertThat(searchHit.getNestedIdentity().getOffset(), equalTo(0));
HighlightField highlightField = searchHit.getHighlightFields().get("message"); HighlightField highlightField = searchHit.getHighlightFields().get("comments.message");
assertThat(highlightField.getFragments().length, equalTo(1)); assertThat(highlightField.getFragments().length, equalTo(1));
assertThat(highlightField.getFragments()[0].string(), equalTo("some <em>comment</em>")); assertThat(highlightField.getFragments()[0].string(), equalTo("some <em>comment</em>"));
@ -849,7 +850,7 @@ public class TopHitsTests extends ElasticsearchIntegrationTest {
nested("to-comments") nested("to-comments")
.path("comments") .path("comments")
.subAggregation(topHits("comments") .subAggregation(topHits("comments")
.addHighlightedField(new HighlightBuilder.Field("message").highlightQuery(matchQuery("comments.message", "text"))) .addHighlightedField(new HighlightBuilder.Field("comments.message").highlightQuery(matchQuery("comments.message", "text")))
.addSort("comments.id", SortOrder.ASC)) .addSort("comments.id", SortOrder.ASC))
) )
) )
@ -872,7 +873,7 @@ public class TopHitsTests extends ElasticsearchIntegrationTest {
assertThat(searchHits.getAt(j).getNestedIdentity().getOffset(), equalTo(0)); assertThat(searchHits.getAt(j).getNestedIdentity().getOffset(), equalTo(0));
assertThat((Integer) searchHits.getAt(j).sourceAsMap().get("id"), equalTo(0)); assertThat((Integer) searchHits.getAt(j).sourceAsMap().get("id"), equalTo(0));
HighlightField highlightField = searchHits.getAt(j).getHighlightFields().get("message"); HighlightField highlightField = searchHits.getAt(j).getHighlightFields().get("comments.message");
assertThat(highlightField.getFragments().length, equalTo(1)); assertThat(highlightField.getFragments().length, equalTo(1));
assertThat(highlightField.getFragments()[0].string(), equalTo("some <em>text</em>")); assertThat(highlightField.getFragments()[0].string(), equalTo("some <em>text</em>"));
} }

View File

@ -98,13 +98,12 @@ public class ExistsMissingTests extends ElasticsearchIntegrationTest {
final Map<String, Integer> expected = new LinkedHashMap<String, Integer>(); final Map<String, Integer> expected = new LinkedHashMap<String, Integer>();
expected.put("foo", 1); expected.put("foo", 1);
expected.put("f*", 2); // foo and bar.foo, that's how the expansion works expected.put("f*", 1);
expected.put("bar", 2); expected.put("bar", 2);
expected.put("bar.*", 2); expected.put("bar.*", 2);
expected.put("bar.foo", 1); expected.put("bar.foo", 1);
expected.put("bar.bar", 1); expected.put("bar.bar", 1);
expected.put("bar.bar.bar", 1); expected.put("bar.bar.bar", 1);
expected.put("baz", 1);
expected.put("foobar", 0); expected.put("foobar", 0);
ensureYellow("idx"); ensureYellow("idx");

View File

@ -510,7 +510,7 @@ public class CompletionSuggestSearchTests extends ElasticsearchIntegrationTest {
assertThat(putMappingResponse.isAcknowledged(), is(true)); assertThat(putMappingResponse.isAcknowledged(), is(true));
SuggestResponse suggestResponse = client().prepareSuggest(INDEX).addSuggestion( SuggestResponse suggestResponse = client().prepareSuggest(INDEX).addSuggestion(
new CompletionSuggestionBuilder("suggs").field("suggest").text("f").size(10) new CompletionSuggestionBuilder("suggs").field(FIELD + ".suggest").text("f").size(10)
).execute().actionGet(); ).execute().actionGet();
assertSuggestions(suggestResponse, "suggs"); assertSuggestions(suggestResponse, "suggs");
@ -553,7 +553,7 @@ public class CompletionSuggestSearchTests extends ElasticsearchIntegrationTest {
assertThat(putMappingResponse.isAcknowledged(), is(true)); assertThat(putMappingResponse.isAcknowledged(), is(true));
SuggestResponse suggestResponse = client().prepareSuggest(INDEX).addSuggestion( SuggestResponse suggestResponse = client().prepareSuggest(INDEX).addSuggestion(
SuggestBuilders.completionSuggestion("suggs").field("suggest").text("f").size(10) SuggestBuilders.completionSuggestion("suggs").field(FIELD + ".suggest").text("f").size(10)
).execute().actionGet(); ).execute().actionGet();
assertSuggestions(suggestResponse, "suggs"); assertSuggestions(suggestResponse, "suggs");