Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Z value support to geo_point and geo_shape #25738

Merged
merged 1 commit into from Mar 23, 2018

Conversation

nknize
Copy link
Contributor

@nknize nknize commented Jul 15, 2017

This enhancement adds Z value support (source only) to geo_shape fields. If vertices are provided with a third dimension, the third dimension is ignored for indexing but returned as part of source. Like before, any values greater than the 3rd dimension are ignored.

closes #22917

@nknize nknize added :Analytics/Geo Indexing, search aggregations of geo points and shapes review v5.6.0 v6.0.0 labels Jul 15, 2017
}

protected static void writeCoordinateTo(Coordinate coordinate, StreamOutput out) throws IOException {
out.writeDouble(coordinate.x);
out.writeDouble(coordinate.y);
out.writeOptionalDouble(Double.isNaN(coordinate.z) ? null : coordinate.z);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need to add a version check here?

return new Coordinate(in.readDouble(), in.readDouble());
double x = in.readDouble();
double y = in.readDouble();
Double z = in.readOptionalDouble();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need to add a version check here?

.coordinate(new Coordinate(-45, -30, 101))
.coordinate(new Coordinate(-45, 30, 110)));

assertEquals(expected, pb.toString());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should test parsing too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added testParse3DPolygon to GeoJSONShapeParserTests

@hanoch
Copy link

hanoch commented Jul 17, 2017

@nknize #22917 talks about both geo_point and geo_shape. does this PR include support for store-and-retrieve Z values for geo_point as well, or will that support be separate from this PR?

@nknize
Copy link
Contributor Author

nknize commented Aug 2, 2017

@hanoch geo_point already supports Z values in source.

geopoint_stored_z

This PR effectively fixes a bug where Z values for geo_shape coordinates were omitted in source after indexing.

@nknize nknize force-pushed the enhancement/22917 branch 2 times, most recently from 52ee020 to fdf07e0 Compare September 19, 2017 17:38
@javanna
Copy link
Member

javanna commented Nov 6, 2017

@nknize are you still working on this?

@hanoch
Copy link

hanoch commented Nov 6, 2017

@nknize we are still waiting for this functionality to be merged into the master branch.

@hanoch
Copy link

hanoch commented Nov 6, 2017

cc: @sherry-ger

@nknize nknize requested a review from colings86 November 9, 2017 03:06
@nknize nknize force-pushed the enhancement/22917 branch 2 times, most recently from 1744096 to 0a7868d Compare November 9, 2017 23:53
@nknize
Copy link
Contributor Author

nknize commented Nov 10, 2017

@colings86 This should be good to go. Could you give it a final once over since @jpountz is out? Thx

@clintongormley
Copy link

Discussed this in FixItFriday. We're not crazy about accepting parameters that we will silently ignore, but given that Z values are part of the geojson spec, we should probably make an effort to extract what info we can from valid geojson files.

It should, however, be enabled by opting in using a mapping parameter like accept_but_ignore_z_values, which makes clear to the user what they are opting in to.

Copy link
Contributor

@colings86 colings86 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nknize this looks ok to me but could you add the option that @clintongormley mentioned and a tests with 3 dimensional polygons with and without that setting?

@hanoch
Copy link

hanoch commented Feb 9, 2018

are we finally ready to merge this to master anytime soon?

@hanoch
Copy link

hanoch commented Feb 14, 2018

@colings86 @jpountz @nknize is this now ready to be merged to master to be able to address #22917?

@nknize nknize changed the title Add Z value support to geo_shape Add Z value support to geo_point and geo_shape Feb 20, 2018
@nknize nknize added the review label Feb 20, 2018
@nknize
Copy link
Contributor Author

nknize commented Feb 20, 2018

Rebased to master and cleaned up some geo_point parsing. This is ready for another review and should be just about ready to merge. /cc @jpountz @colings86

Copy link
Contributor

@colings86 colings86 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, its a shame the changes are so pervasive in the code and the acceptZValue option has to be passed around so much but unfortunately I don't think there is a better way to do it.

Copy link
Contributor

@jpountz jpountz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for making the docs very explicit about how the 3rd dimension is handled. I left some comments but it looks like it is on the right track to me.

@@ -173,6 +173,10 @@ public String toWKT() {
throw new UnsupportedOperationException("The WKT spec does not support CIRCLE geometry");
}

public int numDimensions() {
return center.z == Double.NaN ? 2 : 3;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, yes... thank you. I still slip up w/ this one occasionally.

this.points.add(coordinate);
if (points.isEmpty() == false && Double.isNaN(points.get(0).z) != Double.isNaN(coordinate.z)) {
throw new ElasticsearchException("unable to add coordinate to CoordinateBuilder: " +
"coordinate dimensions do not match");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add the expected number of dims and the new coordinate to the error message?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@@ -452,12 +472,15 @@ public Query termQuery(Object value, QueryShardContext context) {

protected Explicit<Boolean> coerce;
protected Explicit<Boolean> ignoreMalformed;
protected Explicit<Boolean> storeZValue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't seem to be making decisions based on this option? or do I miss it?

@@ -105,6 +105,13 @@ The following parameters are accepted by `geo_point` fields:
If `true`, malformed geo-points are ignored. If `false` (default),
malformed geo-points throw an exception and reject the whole document.

<<accept_z_value,`accept_z_value`>>::
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should it be called something like ignore_z_value instead to make it clear it's ignored?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

* @param ch the char to count
* @return the number of occurrences, 0 if the CharSequence is {@code null}
*/
public static int countMatches(final CharSequence str, final char ch) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reading the rest of the PR, it doesn't seem like we really need this method? We could just check whether the string contains a comma to know whether it is a geohash and then use the length of the array after splitting to know the number of dimensions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

double lat = Double.NaN;
double lon = Double.NaN;
double alt = Double.NaN;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for this alt variable

double x = in.readDouble();
double y = in.readDouble();
Double z = null;
if (in.getVersion().onOrAfter(Version.V_6_0_0_beta1)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs to be version 6.3 now

@@ -123,6 +130,9 @@ public void writeTo(StreamOutput out) throws IOException {
protected static void writeCoordinateTo(Coordinate coordinate, StreamOutput out) throws IOException {
out.writeDouble(coordinate.x);
out.writeDouble(coordinate.y);
if (out.getVersion().onOrAfter(Version.V_6_1_0)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be 6.3

if (token == XContentParser.Token.VALUE_NUMBER) {
GeoPoint.assertZValue(acceptZValue);
alt = parser.doubleValue();
}
while (token == XContentParser.Token.VALUE_NUMBER) {
token = parser.nextToken();
}
// todo support z/alt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove todo

}

public static class Defaults {
public static final Explicit<Boolean> IGNORE_MALFORMED = new Explicit<>(false, false);
public static final GeoPointFieldType FIELD_TYPE = new GeoPointFieldType();
public static final Explicit<Boolean> ACCEPT_Z_VALUE = new Explicit<>(true, false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true by default? shouldn't it be false like the docs say? (we might need some logic to make it true for pre-6.3 indices in case we used to accept it in the past)

Copy link
Contributor

@jpountz jpountz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logic looks good to me overall. I think we should make the default of ignore_z_value false as it could otherwise be a bit trappy? For shapes we can do it directly in this PR since they never supported 3 dimensions (if my understanding is correct). And for points which were always lenient until now (again, if my understanding is correct), we would make the default true in this PR (like you did) but do a follow-up PR to change the default to false on 7.0+ indices


public GeoPoint resetFromString(String value, final boolean ignoreZValue) {
if (value.contains(",")) {
String[] vals = value.split(",");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please fail if vals.length > 3

Copy link

@hanoch hanoch Feb 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jpountz @nknize Wouldn't it be better to be more lenient and accept the first 3 (or 2) dimensions, rather than completely fail? Adding failure now might break compatibility with previous behavior.

@@ -100,6 +100,7 @@
public static final double LEGACY_DISTANCE_ERROR_PCT = 0.025d;
public static final Explicit<Boolean> COERCE = new Explicit<>(false, false);
public static final Explicit<Boolean> IGNORE_MALFORMED = new Explicit<>(false, false);
public static final Explicit<Boolean> ACCEPT_Z_VALUE = new Explicit<>(true, false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/ACCEPT/IGNORE/

double alt = Double.NaN;
if (token == XContentParser.Token.VALUE_NUMBER) {
alt = GeoPoint.assertZValue(ignoreZValue, parser.doubleValue());
}
while (token == XContentParser.Token.VALUE_NUMBER) {
token = parser.nextToken();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's remove this leniency?

@hanoch
Copy link

hanoch commented Feb 23, 2018

@jpountz @nknize what is the overall design goal wrt the default behavior with Z values with geo_shape and geo_point?
It would be best if the default setting and behavior will continue to be that if the data value (csv-string/array/GeoJson/etc.) has a third Z dimension - it will be stored without needing to set any special settings. Also, it will be best to continue to auto ignore any 4th (e.g. M value) and above dimension in the data by default (without adjusting setting to accept the data) and store the first 3 (or 2 if the Z value is not present) dimensions, without failing if there is a 4th or more dimension.
That behavior will be consistent with the existing geo_point [x,y,z] or [x,y] array data values (and we should match the csv-string values with a Z value "y,x,z" or "y,x" as well) of existing and previous releases, where if the data has a Z value it will be stored, without needing to set some special settings, or modify the default settings.
Is that the design?

@colings86
Copy link
Contributor

colings86 commented Feb 23, 2018

@hanoch we do not want the Z Values to be accepted by default because it can be surprising to users. The fact that the z value is accepted but is not indexed and therefore does not affect search results is not what a user would expect OOTB so we feel it is a better user experience for the user to opt-in to accepting but ignoring the Z-Value.

@hanoch
Copy link

hanoch commented Mar 20, 2018

is there anything else pending or are we ready to merge this PR?

@nknize nknize force-pushed the enhancement/22917 branch 2 times, most recently from 05cc21a to 59c65a6 Compare March 23, 2018 13:46
This enhancement adds Z value support (source only) to geo_shape fields. If vertices are provided with a third dimension, the third dimension is ignored for indexing but returned as part of source. Like beofre, any values greater than the 3rd dimension are ignored.

closes elastic#23747
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Analytics/Geo Indexing, search aggregations of geo points and shapes >feature v6.3.0 v7.0.0-beta1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Z values support to geo_point and geo_shape
8 participants