Skip to content

Commit 768434d

Browse files
[8.19] Do not respect synthetic_source_keep=arrays if type parses arrays (#127796) (#127999)
* Do not respect synthetic_source_keep=arrays if type parses arrays (#127796) Types that parse arrays directly should not need to store values in _ignored_source if synthetic_source_keep=arrays. Since they have custom handling of arrays, it provides no benefit to store in _ignored_source when there are multiple values of the type. (cherry picked from commit c04a956) * Broke some stuff while merging
1 parent f6fe428 commit 768434d

File tree

4 files changed

+18
-68
lines changed

4 files changed

+18
-68
lines changed

docs/changelog/127796.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 127796
2+
summary: Do not respect synthetic_source_keep=arrays if type parses arrays
3+
area: Mapping
4+
type: enhancement
5+
issues:
6+
- 126155

docs/reference/mapping/types/geo-point.asciidoc

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,10 @@ any issues, but features in technical preview are not subject to the support SLA
220220
of official GA features.
221221

222222
Synthetic source may sort `geo_point` fields (first by latitude and then
223-
longitude) and reduces them to their stored precision. For example:
223+
longitude) and reduces them to their stored precision. Additionally, unlike most
224+
types, arrays of `geo_point` fields will not preserve order if
225+
`synthetic_source_keep` is set to `arrays`. For example:
226+
224227
[source,console,id=synthetic-source-geo-point-example]
225228
----
226229
PUT idx
@@ -236,15 +239,18 @@ PUT idx
236239
},
237240
"mappings": {
238241
"properties": {
239-
"point": { "type": "geo_point" }
242+
"point": {
243+
"type": "geo_point",
244+
"synthetic_source_keep": "arrays"
245+
}
240246
}
241247
}
242248
}
243249
PUT idx/_doc/1
244250
{
245251
"point": [
246-
{"lat":-90, "lon":-80},
247-
{"lat":10, "lon":30}
252+
{"lat":10, "lon":30},
253+
{"lat":-90, "lon":-80}
248254
]
249255
}
250256
----

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ static void parseObjectOrField(DocumentParserContext context, Mapper mapper) thr
460460
if (context.canAddIgnoredField()
461461
&& (fieldMapper.syntheticSourceMode() == FieldMapper.SyntheticSourceMode.FALLBACK
462462
|| sourceKeepMode == Mapper.SourceKeepMode.ALL
463-
|| (sourceKeepMode == Mapper.SourceKeepMode.ARRAYS && context.inArrayScope())
463+
|| (sourceKeepMode == Mapper.SourceKeepMode.ARRAYS && context.inArrayScope() && parsesArrayValue(mapper) == false)
464464
|| (context.isWithinCopyTo() == false && context.isCopyToDestinationField(mapper.fullPath())))) {
465465
context = context.addIgnoredFieldFromContext(
466466
IgnoredSourceFieldMapper.NameValue.fromContext(context, fieldMapper.fullPath(), null)

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

Lines changed: 1 addition & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import org.elasticsearch.index.mapper.MappedFieldType;
1818

1919
import java.nio.ByteOrder;
20-
import java.util.ArrayList;
2120
import java.util.Comparator;
2221
import java.util.List;
2322
import java.util.Map;
@@ -30,10 +29,7 @@ public GeoPointFieldBlockLoaderTests(BlockLoaderTestCase.Params params) {
3029

3130
@Override
3231
@SuppressWarnings("unchecked")
33-
protected Object expected(Map<String, Object> fieldMapping, Object value, TestContext testContext) {
34-
var extractedFieldValues = (ExtractedFieldValues) value;
35-
var values = extractedFieldValues.values();
36-
32+
protected Object expected(Map<String, Object> fieldMapping, Object values, TestContext testContext) {
3733
var rawNullValue = fieldMapping.get("null_value");
3834

3935
GeoPoint nullValue;
@@ -80,9 +76,6 @@ protected Object expected(Map<String, Object> fieldMapping, Object value, TestCo
8076
if (syntheticSourceKeep.equals("all")) {
8177
return exactValuesFromSource(values, nullValue, false);
8278
}
83-
if (syntheticSourceKeep.equals("arrays") && extractedFieldValues.documentHasObjectArrays()) {
84-
return exactValuesFromSource(values, nullValue, false);
85-
}
8679

8780
// synthetic source and doc_values are present
8881
if (hasDocValues(fieldMapping, true)) {
@@ -117,61 +110,6 @@ private Object exactValuesFromSource(Object value, GeoPoint nullValue, boolean n
117110
return maybeFoldList(resultList);
118111
}
119112

120-
private record ExtractedFieldValues(Object values, boolean documentHasObjectArrays) {}
121-
122-
@Override
123-
protected Object getFieldValue(Map<String, Object> document, String fieldName) {
124-
var extracted = new ArrayList<>();
125-
var documentHasObjectArrays = processLevel(document, fieldName, extracted, false);
126-
127-
if (extracted.size() == 1) {
128-
return new ExtractedFieldValues(extracted.get(0), documentHasObjectArrays);
129-
}
130-
131-
return new ExtractedFieldValues(extracted, documentHasObjectArrays);
132-
}
133-
134-
@SuppressWarnings("unchecked")
135-
private boolean processLevel(Map<String, Object> level, String field, ArrayList<Object> extracted, boolean documentHasObjectArrays) {
136-
if (field.contains(".") == false) {
137-
var value = level.get(field);
138-
processLeafLevel(value, extracted);
139-
return documentHasObjectArrays;
140-
}
141-
142-
var nameInLevel = field.split("\\.")[0];
143-
var entry = level.get(nameInLevel);
144-
if (entry instanceof Map<?, ?> m) {
145-
return processLevel((Map<String, Object>) m, field.substring(field.indexOf('.') + 1), extracted, documentHasObjectArrays);
146-
}
147-
if (entry instanceof List<?> l) {
148-
for (var object : l) {
149-
processLevel((Map<String, Object>) object, field.substring(field.indexOf('.') + 1), extracted, true);
150-
}
151-
return true;
152-
}
153-
154-
assert false : "unexpected document structure";
155-
return false;
156-
}
157-
158-
private void processLeafLevel(Object value, ArrayList<Object> extracted) {
159-
if (value instanceof List<?> l) {
160-
if (l.size() > 0 && l.get(0) instanceof Double) {
161-
// this must be a single point in array form
162-
// we'll put it into a different form here to make our lives a bit easier while implementing `expected`
163-
extracted.add(Map.of("type", "point", "coordinates", l));
164-
} else {
165-
// this is actually an array of points but there could still be points in array form inside
166-
for (var arrayValue : l) {
167-
processLeafLevel(arrayValue, extracted);
168-
}
169-
}
170-
} else {
171-
extracted.add(value);
172-
}
173-
}
174-
175113
@SuppressWarnings("unchecked")
176114
private GeoPoint convert(Object value, GeoPoint nullValue, boolean needsMultifieldAdjustment) {
177115
if (value == null) {

0 commit comments

Comments
 (0)