Session: Querying: How to Query a Spatial Index
Spatial indexes can be queried using the Spatial
method which contains a full spectrum of spatial methods. The following article will cover these methods:
Spatial
IRavenQueryable<T> Spatial<T>(
Expression<Func<T, object>> path,
Func<SpatialCriteriaFactory, SpatialCriteria> clause);
IRavenQueryable<T> Spatial<T>(
string fieldName,
Func<SpatialCriteriaFactory, SpatialCriteria> clause);
IRavenQueryable<T> Spatial<T>(
Func<DynamicSpatialFieldFactory<T>, DynamicSpatialField> field,
Func<SpatialCriteriaFactory, SpatialCriteria> clause);
IRavenQueryable<T> Spatial<T>(
DynamicSpatialField field,
Func<SpatialCriteriaFactory, SpatialCriteria> clause);
Parameters | ||
---|---|---|
path | Expression<Func<T, object>> |
Path to spatial field in an index |
fieldName | string | Path to spatial field in an index |
field | Func<DynamicSpatialFieldFactory<T>, DynamicSpatialField> or DynamicSpatialField |
Factory or field that points to a dynamic field (used with auto-indexes). Either PointField or WktField |
clause | Func<SpatialCriteriaFactory, SpatialCriteria> |
Spatial criteria that will be executed on a given spatial field from the path parameter. |
DynamicSpatialFieldFactory
PointField Point(
Expression<Func<T, object>> latitudePath,
Expression<Func<T, object>> longitudePath);
WktField Wkt(Expression<Func<T, object>> wktPath);
Parameters | ||
---|---|---|
latitudePath or longitudePath or wktPath | Expression<Func<T, object>> |
Path to the field in a document containing either longitude, latitude or WKT |
SpatialCriteriaFactory
SpatialCriteria RelatesToShape(
string shapeWkt,
SpatialRelation relation,
double distErrorPercent = Constants.Documents.Indexing.Spatial.DefaultDistanceErrorPct);
SpatialCriteria RelatesToShape(
string shapeWkt,
SpatialRelation relation,
SpatialUnits units,
double distErrorPercent = Constants.Documents.Indexing.Spatial.DefaultDistanceErrorPct);
SpatialCriteria Intersects(
string shapeWkt,
double distErrorPercent = Constants.Documents.Indexing.Spatial.DefaultDistanceErrorPct);
SpatialCriteria Intersects(
string shapeWkt,
SpatialUnits units,
double distErrorPercent = Constants.Documents.Indexing.Spatial.DefaultDistanceErrorPct);
SpatialCriteria Contains(
string shapeWkt,
double distErrorPercent = Constants.Documents.Indexing.Spatial.DefaultDistanceErrorPct);
SpatialCriteria Contains(
string shapeWkt,
SpatialUnits units,
double distErrorPercent = Constants.Documents.Indexing.Spatial.DefaultDistanceErrorPct);
SpatialCriteria Disjoint(
string shapeWkt,
double distErrorPercent = Constants.Documents.Indexing.Spatial.DefaultDistanceErrorPct);
SpatialCriteria Disjoint(
string shapeWkt,
SpatialUnits units,
double distErrorPercent = Constants.Documents.Indexing.Spatial.DefaultDistanceErrorPct);
SpatialCriteria Within(
string shapeWkt,
double distErrorPercent = Constants.Documents.Indexing.Spatial.DefaultDistanceErrorPct);
SpatialCriteria Within(
string shapeWkt,
SpatialUnits units,
double distErrorPercent = Constants.Documents.Indexing.Spatial.DefaultDistanceErrorPct);
SpatialCriteria WithinRadius(
double radius,
double latitude,
double longitude,
SpatialUnits? radiusUnits = null,
double distErrorPercent = Constants.Documents.Indexing.Spatial.DefaultDistanceErrorPct);
Parameters | ||
---|---|---|
shapeWkt | string | WKT-based shape to be used in operation |
relation | SpatialRelation |
Shape relation. Can be Within , Contains , Disjoint , Intersects |
distErrorPercent | double | Maximum distance error tolerance in percents. Default: 0.025 |
radius or latitude or longitude | double | Used to define a radius circle |
radiusUnits or units | SpatialUnits |
Determines if circle or shape should be calculated in Kilometers or Miles |
Polygons
When using spatial.wkt()
to define a polygon, the vertices (points that form the corners of the polygon) must be listed
in a counter-clockwise order:
Example I
// return all matching entities
// within 10 kilometers radius
// from 32.1234 latitude and 23.4321 longitude coordinates
List<House> results = session
.Query<House>()
.Spatial(
factory => factory.Point(x => x.Latitude, x => x.Longitude),
criteria => criteria.WithinRadius(10, 32.1234, 23.4321))
.ToList();
// return all matching entities
// within 10 kilometers radius
// from 32.1234 latitude and 23.4321 longitude coordinates
List<House> results = await asyncSession
.Query<House>()
.Spatial(
factory => factory.Point(x => x.Latitude, x => x.Longitude),
criteria => criteria.WithinRadius(10, 32.1234, 23.4321))
.ToListAsync();
from Houses
where spatial.within(spatial.point(Latitude, Longitude), spatial.circle(10, 32.1234, 23.4321))
Example II
// return all matching entities
// within 10 miles radius
// from 32.1234 latitude and 23.4321 longitude coordinates
// this equals to WithinRadius(10, 32.1234, 23.4321)
List<House> results = session
.Query<House>()
.Spatial(
factory => factory.Point(x => x.Latitude, x => x.Longitude),
criteria => criteria.RelatesToShape(
"Circle(32.1234 23.4321 d=10.0000)",
SpatialRelation.Within,
SpatialUnits.Miles))
.ToList();
// return all matching entities
// within 10 miles radius
// from 32.1234 latitude and 23.4321 longitude coordinates
// this equals to WithinRadius(10, 32.1234, 23.4321)
List<House> results = await asyncSession
.Query<House>()
.Spatial(
factory => factory.Point(x => x.Latitude, x => x.Longitude),
criteria => criteria.RelatesToShape(
"Circle(32.1234 23.4321 d=10.0000)",
SpatialRelation.Within,
SpatialUnits.Miles))
.ToListAsync();
from Houses
where spatial.within(spatial.point(Latitude, Longitude), spatial.wkt('Circle(32.1234 23.4321 d=10.0000)', 'Miles'))
OrderByDistance
To sort by distance from given point use the OrderByDistance
method. The closest results will come first.
IOrderedQueryable<T> OrderByDistance<T>(
Func<DynamicSpatialFieldFactory<T>, DynamicSpatialField> field,
double latitude,
double longitude);
IOrderedQueryable<T> OrderByDistance<T>(
DynamicSpatialField field,
double latitude,
double longitude);
IOrderedQueryable<T> OrderByDistance<T>(
Expression<Func<T, object>> path,
double latitude,
double longitude);
IOrderedQueryable<T> OrderByDistance<T>(
string fieldName,
double latitude,
double longitude);
IOrderedQueryable<T> OrderByDistance<T>(
Func<DynamicSpatialFieldFactory<T>, DynamicSpatialField> field,
string shapeWkt);
IOrderedQueryable<T> OrderByDistance<T>(
DynamicSpatialField field,
string shapeWkt);
IOrderedQueryable<T> OrderByDistance<T>(
Expression<Func<T, object>> path,
string shapeWkt);
IOrderedQueryable<T> OrderByDistance<T>(
string fieldName,
string shapeWkt);
Parameters | ||
---|---|---|
path | Expression<Func<T, object>> |
Path to spatial field in index |
fieldName | string | Path to spatial field in index |
field | Func<DynamicSpatialFieldFactory<T>, DynamicSpatialField> or DynamicSpatialField |
Factory or field that points to a dynamic field (used with auto-indexes). Either PointField or WktField |
shapeWkt | string | WKT-based shape to be used as a point from which distance will be measured. If the shape is not a single point, then the center of the shape will be used as a reference. |
latitude or longitude | double | Used to define a point from which distance will be measured |
Example
// return all matching entities
// within 10 kilometers radius
// from 32.1234 latitude and 23.4321 longitude coordinates
// sort results by distance from 32.1234 latitude and 23.4321 longitude point
List<House> results = session
.Query<House>()
.Spatial(
factory => factory.Point(x => x.Latitude, x => x.Longitude),
criteria => criteria.WithinRadius(10, 32.1234, 23.4321))
.OrderByDistance(
factory => factory.Point(x => x.Latitude, x => x.Longitude), 32.1234, 23.4321)
.ToList();
// return all matching entities
// within 10 kilometers radius
// from 32.1234 latitude and 23.4321 longitude coordinates
// sort results by distance from 32.1234 latitude and 23.4321 longitude point
List<House> results = await asyncSession
.Query<House>()
.Spatial(
factory => factory.Point(x => x.Latitude, x => x.Longitude),
criteria => criteria.WithinRadius(10, 32.1234, 23.4321))
.OrderByDistance(
factory => factory.Point(x => x.Latitude, x => x.Longitude), 32.1234, 23.4321)
.ToListAsync();
from Houses
where spatial.within(spatial.point(Latitude, Longitude), spatial.circle(10, 32.1234, 23.4321))
order by spatial.distance(spatial.point(Latitude, Longitude), spatial.point(32.1234, 23.4321))
OrderByDistanceDescending
To sort by distance from given point use the OrderByDistanceDescending
method. The farthest results will come first.
IOrderedQueryable<T> OrderByDistanceDescending<T>(
Func<DynamicSpatialFieldFactory<T>, DynamicSpatialField> field,
double latitude,
double longitude);
IOrderedQueryable<T> OrderByDistanceDescending<T>(
DynamicSpatialField field,
double latitude,
double longitude);
IOrderedQueryable<T> OrderByDistanceDescending<T>(
Expression<Func<T, object>> path,
double latitude,
double longitude);
IOrderedQueryable<T> OrderByDistanceDescending<T>(
string fieldName,
double latitude,
double longitude);
IOrderedQueryable<T> OrderByDistanceDescending<T>(
Func<DynamicSpatialFieldFactory<T>, DynamicSpatialField> field,
string shapeWkt);
IOrderedQueryable<T> OrderByDistanceDescending<T>(
DynamicSpatialField field,
string shapeWkt);
IOrderedQueryable<T> OrderByDistanceDescending<T>(
Expression<Func<T, object>> path,
string shapeWkt);
IOrderedQueryable<T> OrderByDistanceDescending<T>(
string fieldName,
string shapeWkt);
Parameters | ||
---|---|---|
path | Expression<Func<T, object>> |
Path to spatial field in an index |
fieldName | string | Path to spatial field in an index |
field | Func<DynamicSpatialFieldFactory<T>, DynamicSpatialField> or DynamicSpatialField |
Factory or field that points to a dynamic field (used with auto-indexes). Either PointField or WktField |
shapeWkt | string | WKT-based shape to be used as a point from which distance will be measured. If the shape is not a single point, then the center of the shape will be used as a reference. |
latitude or longitude | double | Used to define a point from which distance will be measured |
Example
// return all matching entities
// within 10 kilometers radius
// from 32.1234 latitude and 23.4321 longitude coordinates
// sort results by distance from 32.1234 latitude and 23.4321 longitude point
List<House> results = session
.Query<House>()
.Spatial(
factory => factory.Point(x => x.Latitude, x => x.Longitude),
criteria => criteria.WithinRadius(10, 32.1234, 23.4321))
.OrderByDistanceDescending(
factory => factory.Point(x => x.Latitude, x => x.Longitude), 32.1234, 23.4321)
.ToList();
// return all matching entities
// within 10 kilometers radius
// from 32.1234 latitude and 23.4321 longitude coordinates
// sort results by distance from 32.1234 latitude and 23.4321 longitude point
List<House> results = await asyncSession
.Query<House>()
.Spatial(
factory => factory.Point(x => x.Latitude, x => x.Longitude),
criteria => criteria.WithinRadius(10, 32.1234, 23.4321))
.OrderByDistanceDescending(
factory => factory.Point(x => x.Latitude, x => x.Longitude), 32.1234, 23.4321)
.ToListAsync();
from Houses
where spatial.within(spatial.point(Latitude, Longitude), spatial.circle(10, 32.1234, 23.4321))
order by spatial.distance(spatial.point(Latitude, Longitude), spatial.point(32.1234, 23.4321)) desc
Remarks
Note
By default, distances are measured in kilometers.