Skip to content

Commit f3d4074

Browse files
committed
Flattened field type onlt store keyed field.
1 parent 34df28f commit f3d4074

File tree

4 files changed

+70
-18
lines changed

4 files changed

+70
-18
lines changed

server/src/main/java/org/elasticsearch/index/mapper/flattened/FlattenedFieldMapper.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ public static class Builder extends FieldMapper.Builder {
152152
}
153153
});
154154

155+
private final Parameter<Boolean> storeRoot = Parameter.boolParam("store_root", false, m -> builder(m).storeRoot.get(), false);
155156
private final Parameter<Boolean> indexed = Parameter.indexParam(m -> builder(m).indexed.get(), true);
156157
private final Parameter<Boolean> hasDocValues = Parameter.docValuesParam(m -> builder(m).hasDocValues.get(), true);
157158

@@ -245,6 +246,7 @@ private Builder(
245246
protected Parameter<?>[] getParameters() {
246247
return new Parameter<?>[] {
247248
indexed,
249+
storeRoot,
248250
hasDocValues,
249251
depthLimit,
250252
nullValue,
@@ -1105,7 +1107,8 @@ private FlattenedFieldMapper(String leafName, MappedFieldType mappedFieldType, B
11051107
builder.depthLimit.get(),
11061108
builder.ignoreAbove.get(),
11071109
builder.nullValue.get(),
1108-
builder.usesBinaryDocValues
1110+
builder.usesBinaryDocValues,
1111+
builder.storeRoot.get()
11091112
);
11101113
}
11111114

server/src/main/java/org/elasticsearch/index/mapper/flattened/FlattenedFieldParser.java

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class FlattenedFieldParser {
4242
private final String nullValue;
4343

4444
private final boolean usesBinaryDocValues;
45+
private final boolean storeRoot;
4546

4647
FlattenedFieldParser(
4748
String rootFieldFullPath,
@@ -51,7 +52,8 @@ class FlattenedFieldParser {
5152
int depthLimit,
5253
int ignoreAbove,
5354
String nullValue,
54-
boolean usesBinaryDocValues
55+
boolean usesBinaryDocValues,
56+
boolean storeRoot
5557
) {
5658
this.rootFieldFullPath = rootFieldFullPath;
5759
this.keyedFieldFullPath = keyedFieldFullPath;
@@ -61,6 +63,7 @@ class FlattenedFieldParser {
6163
this.ignoreAbove = ignoreAbove;
6264
this.nullValue = nullValue;
6365
this.usesBinaryDocValues = usesBinaryDocValues;
66+
this.storeRoot = storeRoot;
6467
}
6568

6669
public void parse(final DocumentParserContext documentParserContext) throws IOException {
@@ -136,7 +139,8 @@ private void addField(Context context, ContentPath path, String currentName, Str
136139
String keyedValue = createKeyedValue(key, value);
137140
BytesRef bytesKeyedValue = new BytesRef(keyedValue);
138141

139-
if (value.length() > ignoreAbove) {
142+
boolean ignoreRelevant = usesBinaryDocValues == false || fieldType.indexType().hasDenseIndex();
143+
if (ignoreRelevant && value.length() > ignoreAbove) {
140144
if (context.documentParserContext().mappingLookup().isSourceSynthetic()) {
141145
context.documentParserContext.doc().add(new StoredField(keyedIgnoredValuesFieldFullPath, bytesKeyedValue));
142146
}
@@ -145,7 +149,7 @@ private void addField(Context context, ContentPath path, String currentName, Str
145149

146150
// check the keyed value doesn't exceed the IndexWriter.MAX_TERM_LENGTH limit enforced by Lucene at index time
147151
// in that case we can already throw a more user friendly exception here which includes the offending fields key and value lengths
148-
if (bytesKeyedValue.length > IndexWriter.MAX_TERM_LENGTH) {
152+
if (ignoreRelevant && bytesKeyedValue.length > IndexWriter.MAX_TERM_LENGTH) {
149153
String msg = "Flattened field ["
150154
+ rootFieldFullPath
151155
+ "] contains one immense field"
@@ -162,24 +166,30 @@ private void addField(Context context, ContentPath path, String currentName, Str
162166
}
163167
BytesRef bytesValue = new BytesRef(value);
164168
if (fieldType.indexType().hasTerms()) {
165-
context.documentParserContext.doc().add(new StringField(rootFieldFullPath, bytesValue, Field.Store.NO));
169+
if (storeRoot) {
170+
context.documentParserContext.doc().add(new StringField(rootFieldFullPath, bytesValue, Field.Store.NO));
171+
}
166172
context.documentParserContext.doc().add(new StringField(keyedFieldFullPath, bytesKeyedValue, Field.Store.NO));
167173
}
168174

169175
if (fieldType.hasDocValues()) {
170176
if (usesBinaryDocValues) {
171-
MultiValuedBinaryDocValuesField.SeparateCount.addToSeparateCountMultiBinaryFieldInDoc(
172-
context.documentParserContext.doc(),
173-
rootFieldFullPath,
174-
bytesValue
175-
);
177+
if (storeRoot) {
178+
MultiValuedBinaryDocValuesField.SeparateCount.addToSeparateCountMultiBinaryFieldInDoc(
179+
context.documentParserContext.doc(),
180+
rootFieldFullPath,
181+
bytesValue
182+
);
183+
}
176184
MultiValuedBinaryDocValuesField.SeparateCount.addToSeparateCountMultiBinaryFieldInDoc(
177185
context.documentParserContext.doc(),
178186
keyedFieldFullPath,
179187
bytesKeyedValue
180188
);
181189
} else {
182-
context.documentParserContext.doc().add(new SortedSetDocValuesField(rootFieldFullPath, bytesValue));
190+
if (storeRoot) {
191+
context.documentParserContext.doc().add(new SortedSetDocValuesField(rootFieldFullPath, bytesValue));
192+
}
183193
context.documentParserContext.doc().add(new SortedSetDocValuesField(keyedFieldFullPath, bytesKeyedValue));
184194
}
185195

server/src/test/java/org/elasticsearch/index/mapper/flattened/FlattenedFieldMapperTests.java

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public class FlattenedFieldMapperTests extends MapperTestCase {
6363

6464
@Override
6565
protected void minimalMapping(XContentBuilder b) throws IOException {
66-
b.field("type", "flattened");
66+
b.field("type", "flattened").field("store_root", true);
6767
}
6868

6969
@Override
@@ -144,6 +144,33 @@ public void testDefaults() throws Exception {
144144
assertEquals(0, fieldNamesFields.size());
145145
}
146146

147+
public void testDefaults2() throws Exception {
148+
DocumentMapper mapper = createDocumentMapper(fieldMapping(b -> b.field("type", "flattened")));
149+
ParsedDocument parsedDoc = mapper.parse(source(b -> b.startObject("field").field("key", "value").endObject()));
150+
151+
// Check the root fields.
152+
List<IndexableField> fields = parsedDoc.rootDoc().getFields("field");
153+
assertEquals(0, fields.size());
154+
155+
// Check the keyed fields.
156+
List<IndexableField> keyedFields = parsedDoc.rootDoc().getFields("field._keyed");
157+
assertEquals(2, keyedFields.size());
158+
159+
assertEquals("field._keyed", keyedFields.get(0).name());
160+
assertEquals(new BytesRef("key\0value"), keyedFields.get(0).binaryValue());
161+
assertFalse(keyedFields.get(0).fieldType().stored());
162+
assertTrue(keyedFields.get(0).fieldType().omitNorms());
163+
assertEquals(DocValuesType.NONE, keyedFields.get(0).fieldType().docValuesType());
164+
165+
assertEquals("field._keyed", keyedFields.get(1).name());
166+
assertEquals(new BytesRef("key\0value"), keyedFields.get(1).binaryValue());
167+
assertEquals(DocValuesType.SORTED_SET, keyedFields.get(1).fieldType().docValuesType());
168+
169+
// Check that there is no 'field names' field.
170+
List<IndexableField> fieldNamesFields = parsedDoc.rootDoc().getFields(FieldNamesFieldMapper.NAME);
171+
assertEquals(0, fieldNamesFields.size());
172+
}
173+
147174
public void testBinaryDocValuesType() throws Exception {
148175
DocumentMapper mapper = createMapperService(
149176
Settings.builder().put(IndexSettings.USE_TIME_SERIES_DOC_VALUES_FORMAT_SETTING.getKey(), true).build(),
@@ -258,6 +285,7 @@ public void testDisableIndex() throws Exception {
258285
DocumentMapper mapper = createDocumentMapper(fieldMapping(b -> {
259286
b.field("type", "flattened");
260287
b.field("index", false);
288+
b.field("store_root", true);
261289
}));
262290
ParsedDocument parsedDoc = mapper.parse(source(b -> b.startObject("field").field("key", "value").endObject()));
263291

@@ -276,6 +304,7 @@ public void testDisableIndexBinary() throws Exception {
276304
fieldMapping(b -> {
277305
b.field("type", "flattened");
278306
b.field("index", false);
307+
b.field("store_root", true);
279308
})
280309
).documentMapper();
281310
ParsedDocument parsedDoc = mapper.parse(source(b -> b.startObject("field").field("key", "value").endObject()));
@@ -294,6 +323,7 @@ public void testDisableDocValues() throws Exception {
294323
DocumentMapper mapper = createDocumentMapper(fieldMapping(b -> {
295324
b.field("type", "flattened");
296325
b.field("doc_values", false);
326+
b.field("store_root", true);
297327
}));
298328
ParsedDocument parsedDoc = mapper.parse(source(b -> b.startObject("field").field("key", "value").endObject()));
299329

@@ -359,6 +389,7 @@ public void testMixOfOrdinaryAndFlattenedFields() throws Exception {
359389
.startObject("properties")
360390
.startObject("field")
361391
.field("type", "flattened")
392+
.field("store_root", true)
362393
.endObject()
363394
.startObject("a")
364395
.field("type", "object")
@@ -471,6 +502,7 @@ public void testDepthLimit() throws IOException {
471502
// Set a lower value for depth_limit and check that the field is rejected.
472503
merge(mapperService, fieldMapping(b -> {
473504
b.field("type", "flattened");
505+
b.field("store_root", true);
474506
b.field("depth_limit", 2);
475507
}));
476508

@@ -668,11 +700,12 @@ public void testImmenseKeyedTermException() throws IOException {
668700

669701
public void testNullValues() throws Exception {
670702
DocumentMapper mapper = createDocumentMapper(mapping(b -> {
671-
b.startObject("field").field("type", "flattened").endObject();
703+
b.startObject("field").field("type", "flattened").field("store_root", true).endObject();
672704
b.startObject("other_field");
673705
{
674706
b.field("type", "flattened");
675707
b.field("null_value", "placeholder");
708+
b.field("store_root", true);
676709
}
677710
b.endObject();
678711
}));
@@ -732,6 +765,7 @@ public void testDynamicTemplateAndDottedPaths() throws IOException {
732765
b.field("match_mapping_type", "object");
733766
b.startObject("mapping");
734767
b.field("type", "flattened");
768+
b.field("store_root", true);
735769
b.endObject();
736770
b.endObject();
737771
b.endObject();

server/src/test/java/org/elasticsearch/index/mapper/flattened/FlattenedFieldParserTests.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ public void setUp() throws Exception {
4141
Integer.MAX_VALUE,
4242
Integer.MAX_VALUE,
4343
null,
44-
false
44+
false,
45+
true
4546
);
4647
}
4748

@@ -305,7 +306,8 @@ public void testDepthLimit() throws Exception {
305306
2,
306307
Integer.MAX_VALUE,
307308
null,
308-
false
309+
false,
310+
true
309311
);
310312

311313
TestDocumentParserContext context = new TestDocumentParserContext(xContentParser);
@@ -330,7 +332,8 @@ public void testDepthLimitBoundary() throws Exception {
330332
3,
331333
Integer.MAX_VALUE,
332334
null,
333-
false
335+
false,
336+
true
334337
);
335338

336339
TestDocumentParserContext context = new TestDocumentParserContext(xContentParser);
@@ -350,7 +353,8 @@ public void testIgnoreAbove() throws Exception {
350353
Integer.MAX_VALUE,
351354
10,
352355
null,
353-
false
356+
false,
357+
true
354358
);
355359

356360
TestDocumentParserContext context = new TestDocumentParserContext(xContentParser);
@@ -376,7 +380,8 @@ public void testNullValues() throws Exception {
376380
Integer.MAX_VALUE,
377381
Integer.MAX_VALUE,
378382
"placeholder",
379-
false
383+
false,
384+
true
380385
);
381386

382387
TestDocumentParserContext configuredContext = new TestDocumentParserContext(createXContentParser(input));

0 commit comments

Comments
 (0)