Skip to content

Commit aed9477

Browse files
committed
Feedback from MVG on fields with both keyword and text subfields
1 parent 35153c1 commit aed9477

File tree

3 files changed

+14
-9
lines changed

3 files changed

+14
-9
lines changed

server/src/main/java/org/elasticsearch/index/mapper/TextFieldMapper.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,17 +1008,21 @@ protected String delegatingTo() {
10081008
}
10091009
};
10101010
}
1011+
if (isStored()) {
1012+
return new BlockStoredFieldsReader.BytesFromStringsBlockLoader(name());
1013+
}
10111014
/*
10121015
* If this is a sub-text field try and return the parent's loader. Text
10131016
* fields will always be slow to load and if the parent is exact then we
10141017
* should use that instead.
10151018
*/
1019+
// TODO: should this be removed? I think SyntheticSourceHelper already does this:
10161020
String parentField = blContext.parentField(name());
10171021
if (parentField != null) {
10181022
MappedFieldType parent = blContext.lookup().fieldType(parentField);
10191023
if (parent.typeName().equals(KeywordFieldMapper.CONTENT_TYPE)) {
10201024
KeywordFieldMapper.KeywordFieldType kwd = (KeywordFieldMapper.KeywordFieldType) parent;
1021-
if (kwd.hasNormalizer() == false && (kwd.hasDocValues() || kwd.isStored())) {
1025+
if (kwd.hasDocValues() || kwd.isStored()) {
10221026
return new BlockLoader.Delegating(kwd.blockLoader(blContext)) {
10231027
@Override
10241028
protected String delegatingTo() {
@@ -1028,9 +1032,6 @@ protected String delegatingTo() {
10281032
}
10291033
}
10301034
}
1031-
if (isStored()) {
1032-
return new BlockStoredFieldsReader.BytesFromStringsBlockLoader(name());
1033-
}
10341035

10351036
// _ignored_source field will contain entries for this field if it is not stored
10361037
// and there is no syntheticSourceDelegate.
@@ -1579,7 +1580,7 @@ public static KeywordFieldMapper getKeywordFieldMapperForSyntheticSource(Iterabl
15791580
for (Mapper sub : multiFields) {
15801581
if (sub.typeName().equals(KeywordFieldMapper.CONTENT_TYPE)) {
15811582
KeywordFieldMapper kwd = (KeywordFieldMapper) sub;
1582-
if (kwd.hasNormalizer() == false && (kwd.fieldType().hasDocValues() || kwd.fieldType().isStored())) {
1583+
if (kwd.fieldType().hasDocValues() || kwd.fieldType().isStored()) {
15831584
return kwd;
15841585
}
15851586
}

server/src/test/java/org/elasticsearch/index/mapper/blockloader/TextFieldBlockLoaderTests.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,13 @@ public static Object expectedValue(Map<String, Object> fieldMapping, Object valu
3939
var fields = (Map<String, Object>) fieldMapping.get("fields");
4040
if (fields != null) {
4141
var keywordMultiFieldMapping = (Map<String, Object>) fields.get("kwd");
42-
Object normalizer = fields.get("normalizer");
4342
boolean docValues = hasDocValues(keywordMultiFieldMapping, true);
4443
boolean store = keywordMultiFieldMapping.getOrDefault("store", false).equals(true);
4544
Object ignoreAbove = keywordMultiFieldMapping.get("ignore_above");
4645

4746
// See TextFieldMapper.SyntheticSourceHelper#getKeywordFieldMapperForSyntheticSource
4847
// and TextFieldMapper#canUseSyntheticSourceDelegateForLoading().
49-
boolean usingSyntheticSourceDelegate = normalizer == null && (docValues || store);
48+
boolean usingSyntheticSourceDelegate = docValues || store;
5049
boolean canUseSyntheticSourceDelegateForLoading = usingSyntheticSourceDelegate && ignoreAbove == null;
5150
if (canUseSyntheticSourceDelegateForLoading) {
5251
return KeywordFieldBlockLoaderTests.expectedValue(keywordMultiFieldMapping, value, params, testContext);

server/src/test/java/org/elasticsearch/index/mapper/blockloader/TextFieldWithParentBlockLoaderTests.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,18 @@ private Object expected(Map<String, Object> fieldMapping, Object value, BlockLoa
118118
boolean docValues = hasDocValues(fieldMapping, true);
119119
boolean store = fieldMapping.getOrDefault("store", false).equals(true);
120120

121-
if (normalizer == null && (docValues || store)) {
121+
// if text sub field is stored, then always use that:
122+
var textFieldMapping = (Map<String, Object>) ((Map<String, Object>) fieldMapping.get("fields")).get("mf");
123+
if (textFieldMapping.getOrDefault("store", false).equals(true)) {
124+
return TextFieldBlockLoaderTests.expectedValue(textFieldMapping, value, params, testContext);
125+
}
126+
127+
if (docValues || store) {
122128
// we are using block loader of the parent field
123129
return KeywordFieldBlockLoaderTests.expectedValue(fieldMapping, value, params, testContext);
124130
}
125131

126132
// we are using block loader of the text field itself
127-
var textFieldMapping = (Map<String, Object>) ((Map<String, Object>) fieldMapping.get("fields")).get("mf");
128133
return TextFieldBlockLoaderTests.expectedValue(textFieldMapping, value, params, testContext);
129134
}
130135
}

0 commit comments

Comments
 (0)