Skip to content

Commit 4be2f3e

Browse files
committed
Fix defaults in GeoShapeFieldMapper output (#31302)
GeoShapeFieldMapper should show actual defaults instead of placeholder values when the mapping is requested with include_defaults=true. Closes #23206
1 parent e75c51e commit 4be2f3e

File tree

2 files changed

+92
-2
lines changed

2 files changed

+92
-2
lines changed

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

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -555,11 +555,24 @@ protected void doXContentBody(XContentBuilder builder, boolean includeDefaults,
555555
if (includeDefaults || fieldType().tree().equals(Defaults.TREE) == false) {
556556
builder.field(Names.TREE, fieldType().tree());
557557
}
558-
if (includeDefaults || fieldType().treeLevels() != 0) {
558+
559+
if (fieldType().treeLevels() != 0) {
559560
builder.field(Names.TREE_LEVELS, fieldType().treeLevels());
561+
} else if(includeDefaults && fieldType().precisionInMeters() == -1) { // defaults only make sense if precision is not specified
562+
if ("geohash".equals(fieldType().tree())) {
563+
builder.field(Names.TREE_LEVELS, Defaults.GEOHASH_LEVELS);
564+
} else if ("legacyquadtree".equals(fieldType().tree())) {
565+
builder.field(Names.TREE_LEVELS, Defaults.QUADTREE_LEVELS);
566+
} else if ("quadtree".equals(fieldType().tree())) {
567+
builder.field(Names.TREE_LEVELS, Defaults.QUADTREE_LEVELS);
568+
} else {
569+
throw new IllegalArgumentException("Unknown prefix tree type [" + fieldType().tree() + "]");
570+
}
560571
}
561-
if (includeDefaults || fieldType().precisionInMeters() != -1) {
572+
if (fieldType().precisionInMeters() != -1) {
562573
builder.field(Names.TREE_PRESISION, DistanceUnit.METERS.toString(fieldType().precisionInMeters()));
574+
} else if (includeDefaults && fieldType().treeLevels() == 0) { // defaults only make sense if tree levels are not specified
575+
builder.field(Names.TREE_PRESISION, DistanceUnit.METERS.toString(50));
563576
}
564577
if (includeDefaults || fieldType().strategyName() != Defaults.STRATEGY) {
565578
builder.field(Names.STRATEGY, fieldType().strategyName());

server/src/test/java/org/elasticsearch/index/mapper/GeoShapeFieldMapperTests.java

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,16 @@
2727
import org.elasticsearch.common.compress.CompressedXContent;
2828
import org.elasticsearch.common.geo.GeoUtils;
2929
import org.elasticsearch.common.geo.builders.ShapeBuilder;
30+
import org.elasticsearch.common.xcontent.ToXContent;
31+
import org.elasticsearch.common.xcontent.XContentBuilder;
3032
import org.elasticsearch.common.xcontent.XContentFactory;
3133
import org.elasticsearch.plugins.Plugin;
3234
import org.elasticsearch.test.ESSingleNodeTestCase;
3335
import org.elasticsearch.test.InternalSettingsPlugin;
3436

3537
import java.io.IOException;
3638
import java.util.Collection;
39+
import java.util.Collections;
3740

3841
import static org.elasticsearch.index.mapper.GeoPointFieldMapper.Names.IGNORE_Z_VALUE;
3942
import static org.hamcrest.Matchers.containsString;
@@ -517,4 +520,78 @@ public void testEmptyName() throws Exception {
517520
assertThat(e.getMessage(), containsString("name cannot be empty string"));
518521
}
519522

523+
public void testSerializeDefaults() throws Exception {
524+
DocumentMapperParser parser = createIndex("test").mapperService().documentMapperParser();
525+
{
526+
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type1")
527+
.startObject("properties").startObject("location")
528+
.field("type", "geo_shape")
529+
.field("tree", "quadtree")
530+
.endObject().endObject()
531+
.endObject().endObject());
532+
DocumentMapper defaultMapper = parser.parse("type1", new CompressedXContent(mapping));
533+
String serialized = toXContentString((GeoShapeFieldMapper) defaultMapper.mappers().getMapper("location"));
534+
assertTrue(serialized, serialized.contains("\"precision\":\"50.0m\""));
535+
assertTrue(serialized, serialized.contains("\"tree_levels\":21"));
536+
}
537+
{
538+
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type1")
539+
.startObject("properties").startObject("location")
540+
.field("type", "geo_shape")
541+
.field("tree", "geohash")
542+
.endObject().endObject()
543+
.endObject().endObject());
544+
DocumentMapper defaultMapper = parser.parse("type1", new CompressedXContent(mapping));
545+
String serialized = toXContentString((GeoShapeFieldMapper) defaultMapper.mappers().getMapper("location"));
546+
assertTrue(serialized, serialized.contains("\"precision\":\"50.0m\""));
547+
assertTrue(serialized, serialized.contains("\"tree_levels\":9"));
548+
}
549+
{
550+
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type1")
551+
.startObject("properties").startObject("location")
552+
.field("type", "geo_shape")
553+
.field("tree", "quadtree")
554+
.field("tree_levels", "6")
555+
.endObject().endObject()
556+
.endObject().endObject());
557+
DocumentMapper defaultMapper = parser.parse("type1", new CompressedXContent(mapping));
558+
String serialized = toXContentString((GeoShapeFieldMapper) defaultMapper.mappers().getMapper("location"));
559+
assertFalse(serialized, serialized.contains("\"precision\":"));
560+
assertTrue(serialized, serialized.contains("\"tree_levels\":6"));
561+
}
562+
{
563+
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type1")
564+
.startObject("properties").startObject("location")
565+
.field("type", "geo_shape")
566+
.field("tree", "quadtree")
567+
.field("precision", "6")
568+
.endObject().endObject()
569+
.endObject().endObject());
570+
DocumentMapper defaultMapper = parser.parse("type1", new CompressedXContent(mapping));
571+
String serialized = toXContentString((GeoShapeFieldMapper) defaultMapper.mappers().getMapper("location"));
572+
assertTrue(serialized, serialized.contains("\"precision\":\"6.0m\""));
573+
assertFalse(serialized, serialized.contains("\"tree_levels\":"));
574+
}
575+
{
576+
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type1")
577+
.startObject("properties").startObject("location")
578+
.field("type", "geo_shape")
579+
.field("tree", "quadtree")
580+
.field("precision", "6m")
581+
.field("tree_levels", "5")
582+
.endObject().endObject()
583+
.endObject().endObject());
584+
DocumentMapper defaultMapper = parser.parse("type1", new CompressedXContent(mapping));
585+
String serialized = toXContentString((GeoShapeFieldMapper) defaultMapper.mappers().getMapper("location"));
586+
assertTrue(serialized, serialized.contains("\"precision\":\"6.0m\""));
587+
assertTrue(serialized, serialized.contains("\"tree_levels\":5"));
588+
}
589+
}
590+
591+
public String toXContentString(GeoShapeFieldMapper mapper) throws IOException {
592+
XContentBuilder builder = XContentFactory.jsonBuilder().startObject();
593+
mapper.doXContentBody(builder, true, new ToXContent.MapParams(Collections.singletonMap("include_defaults", "true")));
594+
return Strings.toString(builder.endObject());
595+
}
596+
520597
}

0 commit comments

Comments
 (0)