Query a Spatial Index
-
Documents that contain spatial data can be queried by spatial queries that employ geographical criteria.
You have two options:-
Dynamic spatial query
Either make a dynamic spatial query on a collection (see how to make a spatial query).
An auto-index will be created by the server. -
Spatial index query
Or, index your documents' spatial data in a static-index (see indexing spatial data)
and then make a spatial query on this index ( described in this article ).
-
-
A few examples of querying a spatial index are provided below.
A spatial query performed on a static-index is similar to the dynamic spatial query.
Find all spatial API methods listed here. -
Examples in this page:
Search by radius
-
Query the spatial index:
-
Use the
WithinRadius
method to search for all documents containing spatial data that is located
within the specified distance from the given center point.
// Define a spatial query on index 'Events_ByNameAndCoordinates'
List<Event> employeesWithinRadius = session
.Query<Event, Events_ByNameAndCoordinates>()
// Call 'Spatial' method
.Spatial(
// Pass the spatial index-field containing the spatial data
"Coordinates",
// Set the geographical area in which to search for matching documents
// Call 'WithinRadius', pass the radius and the center points coordinates
criteria => criteria.WithinRadius(20, 47.623473, -122.3060097))
.ToList();
// The query returns all matching Event entities
// that are located within 20 kilometers radius
// from point (47.623473 latitude, -122.3060097 longitude).
// Define a spatial query on index 'Events_ByNameAndCoordinates'
List<Event> employeesWithinRadius = session.Advanced
.DocumentQuery<Event, Events_ByNameAndCoordinates>()
// Call 'Spatial' method
.Spatial(
// Pass the spatial index-field containing the spatial data
"Coordinates",
// Set the geographical area in which to search for matching documents
// Call 'WithinRadius', pass the radius and the center points coordinates
criteria => criteria.WithinRadius(20, 47.623473, -122.3060097))
.ToList();
// The query returns all matching Event entities
// that are located within 20 kilometers radius
// from point (47.623473 latitude, -122.3060097 longitude).
// Define an index with a spatial field
public class Events_ByNameAndCoordinates : AbstractIndexCreationTask<Event>
{
public Events_ByNameAndCoordinates()
{
Map = events => from e in events
select new
{
Name = e.Name,
// Call 'CreateSpatialField' to create a spatial index-field
// Field 'Coordinates' will be composed of lat & lng supplied from the document
Coordinates = CreateSpatialField(e.Latitude, e.Longitude)
// Documents can be retrieved
// by making a spatial query on the 'Coordinates' index-field
};
}
}
public class Event
{
public string Id { get; set; }
public string Name { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
}
from index "Events/ByNameAndCoordinates"
where spatial.within(
Coordinates,
spatial.circle(20, 47.623473, -122.3060097)
)
// The query returns all matching Event entities
// that are located within 20 kilometers radius
// from point (47.623473 latitude, -122.3060097 longitude).
Search by shape
-
Query the spatial index:
Use theRelatesToShape
method to search for all documents containing spatial data that is located
in the specified relation to the given shape. -
The shape in the query is specified as either a circle or a polygon in a WKT format.
See polygon rules here. -
The relation to the shape can be one of:
Within
,Contains
,Disjoint
,Intersects
. -
See more usage examples in the dynamic search by shape query.
// Define a spatial query on index 'EventsWithWKT_ByNameAndWKT'
List<EventWithWKT> employeesWithinShape = session
.Query<EventWithWKT, EventsWithWKT_ByNameAndWKT>()
// Call 'Spatial' method
.Spatial(
// Pass the spatial index-field containing the spatial data
"WKT",
// Set the geographical search criteria, call 'RelatesToShape'
criteria => criteria.RelatesToShape(
// Specify the WKT string
shapeWkt: @"POLYGON ((
-118.6527948 32.7114894,
-95.8040242 37.5929338,
-102.8344151 53.3349629,
-127.5286633 48.3485664,
-129.4620208 38.0786067,
-118.7406746 32.7853769,
-118.6527948 32.7114894
))",
// Specify the relation between the WKT shape and the documents spatial data
relation: SpatialRelation.Within))
.ToList();
// The query returns all matching Event entities
// that are located within the specified polygon.
// Define a spatial query on index 'EventsWithWKT_ByNameAndWKT'
List<EventWithWKT> employeesWithinShape = session.Advanced
.DocumentQuery<EventWithWKT, EventsWithWKT_ByNameAndWKT>()
// Call 'Spatial' method
.Spatial(
// Pass the spatial index-field containing the spatial data
"WKT",
// Set the geographical search criteria, call 'RelatesToShape'
criteria => criteria.RelatesToShape(
// Specify the WKT string
shapeWkt: @"POLYGON ((
-118.6527948 32.7114894,
-95.8040242 37.5929338,
-102.8344151 53.3349629,
-127.5286633 48.3485664,
-129.4620208 38.0786067,
-118.7406746 32.7853769,
-118.6527948 32.7114894
))",
// Specify the relation between the WKT shape and the documents spatial data
relation: SpatialRelation.Within))
.ToList();
// The query returns all matching Event entities
// that are located within the specified polygon.
// Define an index with a spatial field
public class EventsWithWKT_ByNameAndWKT : AbstractIndexCreationTask<EventWithWKT>
{
public EventsWithWKT_ByNameAndWKT()
{
Map = events => from e in events
select new
{
Name = e.Name,
// Call 'CreateSpatialField' to create a spatial index-field
// Field 'WKT' will be composed of the WKT string supplied from the document
WKT = CreateSpatialField(e.WKT)
// Documents can be retrieved
// by making a spatial query on the 'WKT' index-field
};
}
}
public class EventWithWKT
{
public string Id { get; set; }
public string Name { get; set; }
public string WKT { get; set; }
}
from index "EventsWithWKT/ByNameAndWKT"
where spatial.within(
WKT,
spatial.wkt("POLYGON ((
-118.6527948 32.7114894,
-95.8040242 37.5929338,
-102.8344151 53.3349629,
-127.5286633 48.3485664,
-129.4620208 38.0786067,
-118.7406746 32.7853769,
-118.6527948 32.7114894))")
)
// The query returns all matching Event entities
// that are located within the specified polygon.
- Note:
The index in the above example indexes a WKT string in the spatial index-field.
However, you can query by shape also on spatial data that is indexed as lat/lng coordinates.
Sort results
-
Query the spatial index:
UseOrderByDistance
orOrderByDistanceDescending
to sort the results by distance from a given point. -
By default, distance in RavenDB measured in kilometers.
The distance can be rounded to a specific range.
// Define a spatial query on index 'Events_ByNameAndCoordinates'
List<Event> employeesSortedByDistance = session
.Query<Event, Events_ByNameAndCoordinates>()
// Filter results by geographical criteria
.Spatial(
"Coordinates",
criteria => criteria.WithinRadius(20, 47.623473, -122.3060097))
// Sort results, call 'OrderByDistance'
.OrderByDistance(
// Pass the spatial index-field containing the spatial data
"Coordinates",
// Sort the results by their distance from this point:
47.623473, -122.3060097)
.ToList();
// Return all matching Event entities located within 20 kilometers radius
// from point (47.623473 latitude, -122.3060097 longitude).
// Sort the results by their distance from a specified point,
// the closest results will be listed first.
// Define a spatial query on index 'Events_ByNameAndCoordinates'
List<Event> employeesSortedByDistance = session.Advanced
.DocumentQuery<Event, Events_ByNameAndCoordinates>()
// Filter results by geographical criteria
.Spatial(
"Coordinates",
criteria => criteria.WithinRadius(20, 47.623473, -122.3060097))
// Sort results, call 'OrderByDistance'
.OrderByDistance(
// Pass the spatial index-field containing the spatial data
"Coordinates",
// Sort the results by their distance from this point:
47.623473, -122.3060097)
.ToList();
// Return all matching Event entities located within 20 kilometers radius
// from point (47.623473 latitude, -122.3060097 longitude).
// Sort the results by their distance from a specified point,
// the closest results will be listed first.
// Define an index with a spatial field
public class Events_ByNameAndCoordinates : AbstractIndexCreationTask<Event>
{
public Events_ByNameAndCoordinates()
{
Map = events => from e in events
select new
{
Name = e.Name,
// Call 'CreateSpatialField' to create a spatial index-field
// Field 'Coordinates' will be composed of lat & lng supplied from the document
Coordinates = CreateSpatialField(e.Latitude, e.Longitude)
// Documents can be retrieved
// by making a spatial query on the 'Coordinates' index-field
};
}
}
public class Event
{
public string Id { get; set; }
public string Name { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
}
from index "Events/ByNameAndCoordinates"
where spatial.within(
Coordinates,
spatial.circle(20, 47.623473, -122.3060097)
)
order by spatial.distance(
Coordinates,
spatial.point(47.623473, -122.3060097)
)
// The query returns all matching Event entities located within 20 kilometers radius
// from point (47.623473 latitude, -122.3060097 longitude).
// Sort the results by their distance from a specified point,
// the closest results will be listed first.
-
More sorting examples are available in the dynamic spatial query article.
-
To get the distance for each resulting entity see get resulting distance.