Querying: Spatial
To perform a spatial search, you can use the Spatial
method which contains a full spectrum of spatial capabilities. You can check the detailed Client API reference for this method here.
Radius Search
The most basic usage and probably most common one is to search for all points or shapes within provided distance from the given center point. To perform this search use the WithinRadius
method.
List<Event> results = session
.Query<Event>()
.Spatial(
factory => factory.Point(x => x.Latitude, x => x.Longitude),
criteria => criteria.WithinRadius(500, 30, 30))
.ToList();
List<Event> results = session
.Advanced
.DocumentQuery<Event>()
.Spatial(
factory => factory.Point(x => x.Latitude, x => x.Longitude),
criteria => criteria.WithinRadius(500, 30, 30))
.ToList();
from Events
where spatial.within(spatial.point(Latitude, Longitude), spatial.circle(500, 30, 30))
Advanced Search
The most advanced (and low-level) method available is RelatesToShape
List<Event> results = session
.Query<Event>()
.Spatial(
factory => factory.Point(x => x.Latitude, x => x.Longitude),
criteria => criteria.RelatesToShape(
shapeWkt: "Circle(30 30 d=500.0000)",
relation: SpatialRelation.Within))
.ToList();
List<Event> results = session
.Advanced
.DocumentQuery<Event>()
.Spatial(
factory => factory.Point(x => x.Latitude, x => x.Longitude),
criteria => criteria.RelatesToShape(
shapeWkt: "Circle(30 30 d=500.0000)",
relation: SpatialRelation.Within))
.ToList();
from Events
where spatial.within(spatial.point(Latitude, Longitude), spatial.wkt('Circle(30 30 d=500.0000)'))
Where the shape is in WKT format and the relation is one of Within
, Contains
, Disjoint
, Intersects
. The above example will yield the same results as the example from the Radius Search
section.
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:
Static Indexes
All of the above examples are using the dynamic querying capabilities of RavenDB and will create automatic indexes to retrieve their results. However, spatial queries can also be performed against static indexes, and this is done in a very similar way.
List<Event> results = session
.Query<Event, Events_ByCoordinates>()
.Spatial(
"Coordinates",
criteria => criteria.WithinRadius(500, 30, 30))
.ToList();
List<Event> results = session
.Advanced
.DocumentQuery<Event>()
.Spatial(
"Coordinates",
criteria => criteria.WithinRadius(500, 30, 30))
.ToList();
public class Events_ByCoordinates : AbstractIndexCreationTask<Event>
{
public Events_ByCoordinates()
{
Map = events => from e in events
select new
{
Coordinates = CreateSpatialField(e.Latitude, e.Longitude)
};
}
}
from index 'Events/ByCoordinates'
where spatial.within(Coordinates, spatial.circle(500, 30, 30))
Information
If you want to know how to setup and customize a spatial field in static index please refer to this article.
Ordering
In order to sort the results by distance, please use the OrderByDistance
or OrderByDistanceDescending
methods. You can read more about them here.
Remarks
Information
Distance in RavenDB by default is measured in kilometers.