Geospatial schema
Three geospatial data types, point, linestring, and polygon, store data that can be searched with geospatial shapes. After creating schema for these data types, geospatial queries can be constructed using them. For most geospatial queries that look for geospatial points, points or linestrings within circles or polygons, DSE Search indexes must also be created.
The examples below load geospatial data with graph.addVertex(…)
commands, but the DSE Graph Loader can be used to load geospatial data starting with DSE 5.0.9 and DSE 5.1.2.
- Point schema
-
-
Create schema for a point and add a vertex with a property value for a point:
schema.propertyKey('name').Text().create() schema.propertyKey('point').Point().withGeoBounds().create() schema.vertexLabel('location').properties('name','point').create() graph.addVertex(label, 'location', 'name', 'Paris', 'point', Geo.point(2.352222, 48.856614))
A vertex label is created for location that has a point property.
For geospatial linestrings, as with geospatial points, the
withGeoBounds()
method limit searches to a default valid range of latitude in degrees from -90 to +90 (South Pole to North Pole) and a valid range of longitude in degrees from -180 to +180 (east to west from the Greenwich Meridian). The point is specified usingGeo.point(longitude, latitude)
when adding the point, using WellKnownText (WKT) format. Note that is specifies longitude first, then latitude.Check that the point exists:
g.V().has('location', 'name', 'Paris').valueMap() ==>{name=[Paris], point=[POINT (2.352222 48.856614)]}
-
Linestring schema
-
Create schema for a linestring and add a vertex with a property value for a linestring:
schema.propertyKey('name').Text().create() schema.propertyKey('line').Linestring().withGeoBounds().create() schema.vertexLabel('lineLocation').properties('name','line').create() graph.addVertex(label, 'lineLocation', 'name', 'ParisLondon', 'line', "LINESTRING(2.352222 48.856614, -0.127758 51.507351)")
A vertex label is created for lineLocation that has a LineString property. The same boundary limits imposed on points are imposed on linestrings.
Check that the linestring exists:
g.V().has('lineLocation','name','ParisLondon').valueMap() ==>{line=[LINESTRING (2.352222 48.856614, -0.127758 51.507351)], name=[ParisLondon]}
-
Polygon schema
-
Create schema for a polygon and add a vertex with a property value for a polygon:
schema.propertyKey('name').Text().create() schema.propertyKey('polygon').Polygon().withGeoBounds().create() schema.vertexLabel('polyLocation').properties('name','polygon').create() graph.addVertex(label, 'polyLocation','name', 'ParisLondonDublin', 'polygon',Geo.polygon(2.352222, 48.856614, -0.127758, 51.507351, -6.26031, 53.349805))
A vertex label is created for polyLocation that has a Polygon property. The same boundary limits imposed on points are imposed on polygons.
Check that the polygon exists:
g.V().has('polyLocation','name','ParisLondonDublin').valueMap() ==>{polygon=[POLYGON ((2.352222 48.856614, -0.127758 51.507351, -6.26031 53.349805, 2.352222 48.856614))], name=[ParisLondonDublin]}
-
DSE Search indexes
-
While DSE Graph natively supports geospatial searches, performing them without a Search index does not scale as the number of vertices in the graph increases. Doing such queries without a search index results in very inefficient query performance because full scans are required. DSE Search indexes can index points and linestrings, but not polygons.
//SEARCH INDEX ONLY WORKS FOR POINT AND LINESTRING schema.vertexLabel('location').index('search').search().by('point').add() schema.vertexLabel('lineLocation').index('search').search().by('line').add()
Without a search index, spatial queries always return exact results. DSE Search indexes, however, can trade off performance for accuracy.
A point of confusion can occur if the same geospatial query is run with or without a DSE Search index. Without a search index, geospatial queries always return exact results. DSE Search indexes, however, trade off write performance and index size for query accuracy with two tunable parameters,
maxDistErr (default: 0.000009)
anddistErrPct (default: 0.025)
. Inconsistent results in these two cases are due to the distance calculation algorithm variation of the default values of these parameters. DSE Graph can pass values for these two parameters when creating the search index. ChangemaxDistErr
inwithError(maxDistErr, distErrPct)
to0.0
to force both index-backed and non-index-backed queries to yield the same value:+
schema.vertexLabel('location').index('search').search().by('point').withError(0.000009,0.0).add()
-
Geospatial queries can be created once schema exists.