percolator: If `index.percolator.map_unmapped_fields_as_string` is enabled then don't replace found fields with dummy string field

Closes #10500
This commit is contained in:
Martijn van Groningen 2016-01-17 22:06:53 +01:00
parent 6c34452409
commit ce89039926
3 changed files with 116 additions and 9 deletions

View File

@ -282,20 +282,14 @@ public class QueryShardContext {
this.mapUnmappedFieldAsString = mapUnmappedFieldAsString;
}
private MappedFieldType failIfFieldMappingNotFound(String name, MappedFieldType fieldMapping) {
if (allowUnmappedFields) {
MappedFieldType failIfFieldMappingNotFound(String name, MappedFieldType fieldMapping) {
if (fieldMapping != null || allowUnmappedFields) {
return fieldMapping;
} else if (mapUnmappedFieldAsString) {
StringFieldMapper.Builder builder = MapperBuilders.stringField(name);
return builder.build(new Mapper.BuilderContext(indexSettings.getSettings(), new ContentPath(1))).fieldType();
} else {
Version indexCreatedVersion = indexSettings.getIndexVersionCreated();
if (fieldMapping == null && indexCreatedVersion.onOrAfter(Version.V_1_4_0_Beta1)) {
throw new QueryShardException(this, "Strict field resolution and no field mapping can be found for the field with name ["
+ name + "]");
} else {
return fieldMapping;
}
throw new QueryShardException(this, "No field mapping can be found for the field with name [{}]", name);
}
}

View File

@ -0,0 +1,83 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.index.query;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.core.StringFieldMapper;
import org.elasticsearch.test.ESTestCase;
import java.util.Collections;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.sameInstance;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class QueryShardContextTests extends ESTestCase {
public void testFailIfFieldMappingNotFound() {
IndexMetaData.Builder indexMetadata = new IndexMetaData.Builder("index");
indexMetadata.settings(Settings.builder().put("index.version.created", Version.CURRENT)
.put("index.number_of_shards", 1)
.put("index.number_of_replicas", 1)
);
IndexSettings indexSettings = new IndexSettings(indexMetadata.build(), Settings.EMPTY);
MapperService mapperService = mock(MapperService.class);
when(mapperService.getIndexSettings()).thenReturn(indexSettings);
QueryShardContext context = new QueryShardContext(
indexSettings, null, null, null, mapperService, null, null, null
);
context.setAllowUnmappedFields(false);
MappedFieldType fieldType = new StringFieldMapper.StringFieldType();
MappedFieldType result = context.failIfFieldMappingNotFound("name", fieldType);
assertThat(result, sameInstance(fieldType));
try {
context.failIfFieldMappingNotFound("name", null);
fail("exception expected");
} catch (QueryShardException e) {
assertThat(e.getMessage(), equalTo("No field mapping can be found for the field with name [name]"));
}
context.setAllowUnmappedFields(true);
result = context.failIfFieldMappingNotFound("name", fieldType);
assertThat(result, sameInstance(fieldType));
result = context.failIfFieldMappingNotFound("name", null);
assertThat(result, nullValue());
context.setAllowUnmappedFields(false);
context.setMapUnmappedFieldAsString(true);
result = context.failIfFieldMappingNotFound("name", fieldType);
assertThat(result, sameInstance(fieldType));
result = context.failIfFieldMappingNotFound("name", null);
assertThat(result, notNullValue());
assertThat(result, instanceOf(StringFieldMapper.StringFieldType.class));
assertThat(result.name(), equalTo("name"));
}
}

View File

@ -18,6 +18,7 @@
*/
package org.elasticsearch.percolator;
import com.vividsolutions.jts.geom.Coordinate;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.action.admin.cluster.node.stats.NodeStats;
import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse;
@ -30,6 +31,7 @@ import org.elasticsearch.action.percolate.PercolateSourceBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.Requests;
import org.elasticsearch.common.geo.builders.ShapeBuilders;
import org.elasticsearch.common.lucene.search.function.CombineFunction;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.Settings.Builder;
@ -71,6 +73,7 @@ import static org.elasticsearch.common.xcontent.XContentFactory.yamlBuilder;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.constantScoreQuery;
import static org.elasticsearch.index.query.QueryBuilders.functionScoreQuery;
import static org.elasticsearch.index.query.QueryBuilders.geoShapeQuery;
import static org.elasticsearch.index.query.QueryBuilders.hasChildQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
@ -1836,6 +1839,33 @@ public class PercolatorIT extends ESIntegTestCase {
assertThat(response1.getMatches(), arrayWithSize(1));
}
public void testGeoShapeWithMapUnmappedFieldAsString() throws Exception {
// If index.percolator.map_unmapped_fields_as_string is set to true, unmapped field is mapped as an analyzed string.
Settings.Builder settings = Settings.settingsBuilder()
.put(indexSettings())
.put("index.percolator.map_unmapped_fields_as_string", true);
assertAcked(prepareCreate("test")
.setSettings(settings)
.addMapping("type", "location", "type=geo_shape"));
client().prepareIndex("test", PercolatorService.TYPE_NAME, "1")
.setSource(jsonBuilder().startObject().field("query", geoShapeQuery("location", ShapeBuilders.newEnvelope(new Coordinate(0d, 50d), new Coordinate(2d, 40d)))).endObject())
.get();
refresh();
PercolateResponse response1 = client().preparePercolate()
.setIndices("test").setDocumentType("type")
.setPercolateDoc(docBuilder().setDoc(jsonBuilder().startObject()
.startObject("location")
.field("type", "point")
.field("coordinates", Arrays.asList(1.44207d, 43.59959d))
.endObject()
.endObject()))
.execute().actionGet();
assertMatchCount(response1, 1L);
assertThat(response1.getMatches().length, equalTo(1));
assertThat(response1.getMatches()[0].getId().string(), equalTo("1"));
}
public void testFailNicelyWithInnerHits() throws Exception {
XContentBuilder mapping = XContentFactory.jsonBuilder().startObject()
.startObject("mapping")