Skip to content

Commit 501c2a7

Browse files
authored
Fix search_as_you_type's sub-fields to pick their names from the full path of the root field (#41541)
The subfields of the search_as_you_type are prefixed with the name of their root field. However they should used the full path of the root field rather than just the name since these fields can appear in a multi-`fields` definition or under an object field. Since this field type is not released yet, this should be considered as a non-issue.
1 parent de22273 commit 501c2a7

File tree

2 files changed

+58
-3
lines changed

2 files changed

+58
-3
lines changed

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,9 @@ public SearchAsYouTypeFieldMapper build(Mapper.BuilderContext context) {
160160
final NamedAnalyzer searchQuoteAnalyzer = fieldType().searchQuoteAnalyzer();
161161

162162
// set up the prefix field
163-
final String prefixFieldName = name() + PREFIX_FIELD_SUFFIX;
164-
final PrefixFieldType prefixFieldType = new PrefixFieldType(name(), prefixFieldName, Defaults.MIN_GRAM, Defaults.MAX_GRAM);
163+
final String fullName = buildFullName(context);
164+
final String prefixFieldName = fullName + PREFIX_FIELD_SUFFIX;
165+
final PrefixFieldType prefixFieldType = new PrefixFieldType(fullName, prefixFieldName, Defaults.MIN_GRAM, Defaults.MAX_GRAM);
165166
prefixFieldType.setIndexOptions(fieldType().indexOptions());
166167
// wrap the root field's index analyzer with shingles and edge ngrams
167168
final SearchAsYouTypeAnalyzer prefixIndexWrapper =
@@ -180,7 +181,7 @@ public SearchAsYouTypeFieldMapper build(Mapper.BuilderContext context) {
180181
for (int i = 0; i < shingleFieldMappers.length; i++) {
181182
final int shingleSize = i + 2;
182183
final ShingleFieldType shingleFieldType = new ShingleFieldType(fieldType(), shingleSize);
183-
shingleFieldType.setName(getShingleFieldName(name(), shingleSize));
184+
shingleFieldType.setName(getShingleFieldName(buildFullName(context), shingleSize));
184185
// wrap the root field's index, search, and search quote analyzers with shingles
185186
final SearchAsYouTypeAnalyzer shingleIndexWrapper =
186187
SearchAsYouTypeAnalyzer.withShingle(indexAnalyzer.analyzer(), shingleSize);

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

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,60 @@ public void testSimpleMerge() throws IOException {
235235
}
236236
}
237237

238+
public void testMultiFields() throws IOException {
239+
for (int shingleSize = 2; shingleSize < 4; shingleSize++) {
240+
final XContentBuilder mapping = XContentFactory.jsonBuilder()
241+
.startObject()
242+
.startObject("properties")
243+
.startObject("a_field")
244+
.field("type", "text")
245+
.startObject("fields")
246+
.startObject("suggest")
247+
.field("type", "search_as_you_type")
248+
.field("max_shingle_size", shingleSize)
249+
.endObject()
250+
.endObject()
251+
.endObject()
252+
.endObject()
253+
.endObject();
254+
255+
final String index = "foo_" + shingleSize;
256+
final String path = "a_field.suggest";
257+
List<String> fields = new ArrayList<>();
258+
fields.add(path);
259+
final MapperService mapperService =
260+
createIndex(index, Settings.EMPTY, "_doc", mapping).mapperService();
261+
FieldType fieldType = mapperService.fullName(path + "._index_prefix");
262+
assertThat(fieldType, instanceOf(PrefixFieldType.class));
263+
PrefixFieldType prefixFieldType = (PrefixFieldType) fieldType;
264+
assertEquals(path, prefixFieldType.parentField);
265+
for (int i = 2; i < shingleSize; i++) {
266+
String name = path + "._" + i + "gram";
267+
fields.add(name);
268+
fieldType = mapperService.fullName(name);
269+
assertThat(fieldType, instanceOf(ShingleFieldType.class));
270+
ShingleFieldType ft = (ShingleFieldType) fieldType;
271+
assertEquals(i, ft.shingleSize);
272+
assertTrue(prefixFieldType == ft.prefixFieldType);
273+
}
274+
275+
ParsedDocument doc = mapperService.documentMapper()
276+
.parse(new SourceToParse("test", "_doc", "1",
277+
BytesReference.bytes(
278+
XContentFactory.jsonBuilder()
279+
.startObject()
280+
.field("a_field", "new york city")
281+
.endObject()
282+
), XContentType.JSON)
283+
);
284+
for (String field : fields) {
285+
IndexableField[] indexFields = doc.rootDoc().getFields(field);
286+
assertEquals(1, indexFields.length);
287+
assertEquals("new york city", indexFields[0].stringValue());
288+
}
289+
}
290+
}
291+
238292
public void testIndexOptions() throws IOException {
239293
final String mapping = Strings.toString(XContentFactory.jsonBuilder()
240294
.startObject()

0 commit comments

Comments
 (0)