Skip to content

Commit ae569a2

Browse files
authored
Fix merging of search_as_you_type field mapper (#40593)
The merge of the `search_as_you_type` field mapper uses the wrong prefix field and does not update the underlying field types.
1 parent 1f392a7 commit ae569a2

File tree

2 files changed

+68
-3
lines changed

2 files changed

+68
-3
lines changed

modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/SearchAsYouTypeFieldMapper.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ protected void parseCreateField(ParseContext context, List<IndexableField> field
516516

517517
@Override
518518
protected String contentType() {
519-
return CONTENT_TYPE;
519+
return "shingle";
520520
}
521521
}
522522

@@ -663,6 +663,16 @@ public SearchAsYouTypeFieldMapper(String simpleName,
663663
this.maxShingleSize = maxShingleSize;
664664
}
665665

666+
@Override
667+
public FieldMapper updateFieldType(Map<String, MappedFieldType> fullNameToFieldType) {
668+
SearchAsYouTypeFieldMapper fieldMapper = (SearchAsYouTypeFieldMapper) super.updateFieldType(fullNameToFieldType);
669+
fieldMapper.prefixField = (PrefixFieldMapper) fieldMapper.prefixField.updateFieldType(fullNameToFieldType);
670+
for (int i = 0; i < fieldMapper.shingleFields.length; i++) {
671+
fieldMapper.shingleFields[i] = (ShingleFieldMapper) fieldMapper.shingleFields[i].updateFieldType(fullNameToFieldType);
672+
}
673+
return fieldMapper;
674+
}
675+
666676
@Override
667677
protected void parseCreateField(ParseContext context, List<IndexableField> fields) throws IOException {
668678
final String value = context.externalValueSet() ? context.externalValue().toString() : context.parser().textOrNull();
@@ -692,10 +702,10 @@ protected void doMerge(Mapper mergeWith) {
692702
super.doMerge(mergeWith);
693703
SearchAsYouTypeFieldMapper mw = (SearchAsYouTypeFieldMapper) mergeWith;
694704
if (mw.maxShingleSize != maxShingleSize) {
695-
throw new IllegalArgumentException("mapper [" + name() + "] has different maxShingleSize setting, current ["
705+
throw new IllegalArgumentException("mapper [" + name() + "] has different [max_shingle_size] setting, current ["
696706
+ this.maxShingleSize + "], merged [" + mw.maxShingleSize + "]");
697707
}
698-
this.prefixField = (PrefixFieldMapper) this.prefixField.merge(mw);
708+
this.prefixField = (PrefixFieldMapper) this.prefixField.merge(mw.prefixField);
699709

700710
ShingleFieldMapper[] shingleFieldMappers = new ShingleFieldMapper[mw.shingleFields.length];
701711
for (int i = 0; i < shingleFieldMappers.length; i++) {

modules/mapper-extras/src/test/java/org/elasticsearch/index/mapper/SearchAsYouTypeFieldMapperTests.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
import static java.util.Arrays.asList;
7272
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.hasProperty;
7373
import static org.hamcrest.Matchers.containsInAnyOrder;
74+
import static org.hamcrest.Matchers.containsString;
7475
import static org.hamcrest.Matchers.equalTo;
7576
import static org.hamcrest.Matchers.hasSize;
7677
import static org.hamcrest.Matchers.notNullValue;
@@ -180,6 +181,60 @@ public void testConfiguration() throws IOException {
180181
getShingleFieldMapper(defaultMapper, "a_field._4gram").fieldType(), 4, analyzerName, prefixFieldMapper.fieldType());
181182
}
182183

184+
public void testSimpleMerge() throws IOException {
185+
MapperService mapperService = createIndex("test").mapperService();
186+
{
187+
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject()
188+
.startObject("_doc")
189+
.startObject("properties")
190+
.startObject("a_field")
191+
.field("type", "search_as_you_type")
192+
.field("analyzer", "standard")
193+
.endObject()
194+
.endObject()
195+
.endObject().endObject());
196+
DocumentMapper mapper = mapperService.merge("_doc",
197+
new CompressedXContent(mapping), MapperService.MergeReason.MAPPING_UPDATE);
198+
}
199+
200+
{
201+
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject()
202+
.startObject("_doc")
203+
.startObject("properties")
204+
.startObject("a_field")
205+
.field("type", "search_as_you_type")
206+
.field("analyzer", "standard")
207+
.endObject()
208+
.startObject("b_field")
209+
.field("type", "text")
210+
.endObject()
211+
.endObject()
212+
.endObject().endObject());
213+
DocumentMapper mapper = mapperService.merge("_doc",
214+
new CompressedXContent(mapping), MapperService.MergeReason.MAPPING_UPDATE);
215+
}
216+
217+
{
218+
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject()
219+
.startObject("_doc")
220+
.startObject("properties")
221+
.startObject("a_field")
222+
.field("type", "search_as_you_type")
223+
.field("analyzer", "standard")
224+
.field("max_shingle_size", "4")
225+
.endObject()
226+
.startObject("b_field")
227+
.field("type", "text")
228+
.endObject()
229+
.endObject()
230+
.endObject().endObject());
231+
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
232+
() -> mapperService.merge("_doc",
233+
new CompressedXContent(mapping), MapperService.MergeReason.MAPPING_UPDATE));
234+
assertThat(e.getMessage(), containsString("different [max_shingle_size]"));
235+
}
236+
}
237+
183238
public void testIndexOptions() throws IOException {
184239
final String mapping = Strings.toString(XContentFactory.jsonBuilder()
185240
.startObject()

0 commit comments

Comments
 (0)