Skip to content

Commit d9a6d69

Browse files
authored
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 340313b commit d9a6d69

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
@@ -546,11 +546,24 @@ protected void doXContentBody(XContentBuilder builder, boolean includeDefaults,
546546
if (includeDefaults || fieldType().tree().equals(Defaults.TREE) == false) {
547547
builder.field(Names.TREE, fieldType().tree());
548548
}
549-
if (includeDefaults || fieldType().treeLevels() != 0) {
549+
550+
if (fieldType().treeLevels() != 0) {
550551
builder.field(Names.TREE_LEVELS, fieldType().treeLevels());
552+
} else if(includeDefaults && fieldType().precisionInMeters() == -1) { // defaults only make sense if precision is not specified
553+
if ("geohash".equals(fieldType().tree())) {
554+
builder.field(Names.TREE_LEVELS, Defaults.GEOHASH_LEVELS);
555+
} else if ("legacyquadtree".equals(fieldType().tree())) {
556+
builder.field(Names.TREE_LEVELS, Defaults.QUADTREE_LEVELS);
557+
} else if ("quadtree".equals(fieldType().tree())) {
558+
builder.field(Names.TREE_LEVELS, Defaults.QUADTREE_LEVELS);
559+
} else {
560+
throw new IllegalArgumentException("Unknown prefix tree type [" + fieldType().tree() + "]");
561+
}
551562
}
552-
if (includeDefaults || fieldType().precisionInMeters() != -1) {
563+
if (fieldType().precisionInMeters() != -1) {
553564
builder.field(Names.TREE_PRESISION, DistanceUnit.METERS.toString(fieldType().precisionInMeters()));
565+
} else if (includeDefaults && fieldType().treeLevels() == 0) { // defaults only make sense if tree levels are not specified
566+
builder.field(Names.TREE_PRESISION, DistanceUnit.METERS.toString(50));
554567
}
555568
if (includeDefaults || fieldType().strategyName() != Defaults.STRATEGY) {
556569
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)