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.
This commit is contained in:
Jim Ferenczi 2019-04-26 10:18:48 +02:00 committed by jimczi
parent 078936b8f5
commit 67820f9da1
2 changed files with 58 additions and 3 deletions

View File

@ -160,8 +160,9 @@ public class SearchAsYouTypeFieldMapper extends FieldMapper {
final NamedAnalyzer searchQuoteAnalyzer = fieldType().searchQuoteAnalyzer();
// set up the prefix field
final String prefixFieldName = name() + PREFIX_FIELD_SUFFIX;
final PrefixFieldType prefixFieldType = new PrefixFieldType(name(), prefixFieldName, Defaults.MIN_GRAM, Defaults.MAX_GRAM);
final String fullName = buildFullName(context);
final String prefixFieldName = fullName + PREFIX_FIELD_SUFFIX;
final PrefixFieldType prefixFieldType = new PrefixFieldType(fullName, prefixFieldName, Defaults.MIN_GRAM, Defaults.MAX_GRAM);
prefixFieldType.setIndexOptions(fieldType().indexOptions());
// wrap the root field's index analyzer with shingles and edge ngrams
final SearchAsYouTypeAnalyzer prefixIndexWrapper =
@ -180,7 +181,7 @@ public class SearchAsYouTypeFieldMapper extends FieldMapper {
for (int i = 0; i < shingleFieldMappers.length; i++) {
final int shingleSize = i + 2;
final ShingleFieldType shingleFieldType = new ShingleFieldType(fieldType(), shingleSize);
shingleFieldType.setName(getShingleFieldName(name(), shingleSize));
shingleFieldType.setName(getShingleFieldName(buildFullName(context), shingleSize));
// wrap the root field's index, search, and search quote analyzers with shingles
final SearchAsYouTypeAnalyzer shingleIndexWrapper =
SearchAsYouTypeAnalyzer.withShingle(indexAnalyzer.analyzer(), shingleSize);

View File

@ -235,6 +235,60 @@ public class SearchAsYouTypeFieldMapperTests extends ESSingleNodeTestCase {
}
}
public void testMultiFields() throws IOException {
for (int shingleSize = 2; shingleSize < 4; shingleSize++) {
final XContentBuilder mapping = XContentFactory.jsonBuilder()
.startObject()
.startObject("properties")
.startObject("a_field")
.field("type", "text")
.startObject("fields")
.startObject("suggest")
.field("type", "search_as_you_type")
.field("max_shingle_size", shingleSize)
.endObject()
.endObject()
.endObject()
.endObject()
.endObject();
final String index = "foo_" + shingleSize;
final String path = "a_field.suggest";
List<String> fields = new ArrayList<>();
fields.add(path);
final MapperService mapperService =
createIndex(index, Settings.EMPTY, "_doc", mapping).mapperService();
FieldType fieldType = mapperService.fullName(path + "._index_prefix");
assertThat(fieldType, instanceOf(PrefixFieldType.class));
PrefixFieldType prefixFieldType = (PrefixFieldType) fieldType;
assertEquals(path, prefixFieldType.parentField);
for (int i = 2; i < shingleSize; i++) {
String name = path + "._" + i + "gram";
fields.add(name);
fieldType = mapperService.fullName(name);
assertThat(fieldType, instanceOf(ShingleFieldType.class));
ShingleFieldType ft = (ShingleFieldType) fieldType;
assertEquals(i, ft.shingleSize);
assertTrue(prefixFieldType == ft.prefixFieldType);
}
ParsedDocument doc = mapperService.documentMapper()
.parse(new SourceToParse("test", "_doc", "1",
BytesReference.bytes(
XContentFactory.jsonBuilder()
.startObject()
.field("a_field", "new york city")
.endObject()
), XContentType.JSON)
);
for (String field : fields) {
IndexableField[] indexFields = doc.rootDoc().getFields(field);
assertEquals(1, indexFields.length);
assertEquals("new york city", indexFields[0].stringValue());
}
}
}
public void testIndexOptions() throws IOException {
final String mapping = Strings.toString(XContentFactory.jsonBuilder()
.startObject()